Selenium gives Server Error 500 after click (Django, pytest) - python

I have a Django app that I want to test via pytest and Selenium.
The routine I'm trying to go through is to let Selenium log in, then go to the menu, choose one of the options. This redirects to a new page, which is found fine. There, I let selenium enter data and click a button to start a submission. This, too, works, and redirects to a third page.
On this third "your submission was created successfully" page, there is a link displayed that the user can click to collect the results of their submission (this page . This link is displayed correctly, the href URL is fine. But when I let Selenium click on it, I suddenly get a Server Error 500:
<html lang="en"><head>
<title>Server Error (500)</title>
</head>
<body>
<h1>Server Error (500)</h1><p></p>
</body></html>
When I do the exact same thing manually, it works fine.
Here's my test code (slightly simplified):
#pytest.fixture(scope="class")
def chrome_driver_init(request):
options = webdriver.ChromeOptions()
options.headless = True
options.binary_location = CHROME_BIN_PATH
driver = webdriver.Chrome(service=CHROME_SERVICE, options=options)
request.cls.driver = driver
yield
driver.quit()
#pytest.mark.django_db
#pytest.mark.usefixtures("chrome_driver_init")
class SubmissionTest(LiveServerTestCase):
def test_adding_submission(self):
self.driver.get(self.live_server_url)
username = TEST_USER
pwd = TEST_USER_PWD
User = get_user_model()
user = User.objects.create_user(username=username, password=pwd)
user.save()
# click 'Login':
self.driver.find_element(By.LINK_TEXT, "Login").click()
# now on Login page, log in via Selenium:
username_field = self.driver.find_element(By.NAME, "username")
pwd_field = self.driver.find_element(By.NAME, "password")
submit_btn = self.driver.find_element(By.ID, "form_field")
username_field.send_keys(TEST_USER)
pwd_field.send_keys(TEST_USER_PWD)
submit_btn.click()
# now logged in, go to desired menu point:
self.driver.find_element(By.LINK_TEXT, "MenuPoint 1").click()
assert self.driver.title == "MenuPoint 1" # redirection works fine
## find various fields, enter stuff, click "submit"
# check successfull:
assert self.driver.title == "Added Submission" # redirection works, as expected
## more checks => yes, this is the desired page
# find link for result page:
result_link = self.driver.find_element(By.LINK_TEXT, "click here for your results")
result_link_url = result_link.get_attribute("href")
print(result_link_url) # this is indeed the correct URL
# click link:
time.sleep(10) # wait 10 seconds => more did not help, either
result_link.click()
## now we get the Server Error :-(
print(self.driver.page_source)
I have already tried to use WebDriverWait(self.driver, 10).until(EC.element_to_be_clickable((By.LINK_TEXT, "click here for your results"))).click(), and that doesn't seem to even click.
I know that error 500 mean's the error is on the server side. But before clicking, the server is fine. All the redirections before this step work fine. The URLs also check out. And manually, everything works as expected. I have no idea how to narrow down the problem further.
How can I investigate the reason for this error, and hopefully fix it?

The test creates only a user instance. Is that enough for the view which fails?
You need to get to server traceback to know for sure what's wrong.
from django.test import override_settings
#pytest.mark.django_db
#pytest.mark.usefixtures("chrome_driver_init")
class SubmissionTest(LiveServerTestCase):
#override_settings(DEBUG=True)
def test_adding_submission(self):
...
Take a look at Django: why i can't get the tracebacks (in case of error) when i run LiveServerTestCase tests? for more details.

Related

Using playwright for python, how can I click a button?

First time using playwright. Trying to log in to Pinterest.
browser = playwright.chromium.launch(headless=False)
context = browser.new_context()
page = context.new_page()
page.goto('https://pinterest.co.uk/login')
# Interact with login form
page.fill('input[name="id"]', email)
page.fill('input[name="password"]', password)
# looking for the login button. This part breaks.
page.locator('xpath=//*[#id="__PWS_ROOT__"]/div[1]/div/div[2]/div/div/div/div/div/div[4]/form/div[5]/button').click()
#open the form to create a pin
page.goto('https://www.pinterest.co.uk/pin-builder/')
I get a timeout error because it's waiting for the selector with the given xpath, but it's probably not finding it. Any ideas?
You should be able to get that button by text:
page.locator('"Log in"').click()
Try this one hope it will work for your machine too.
you cannot use xpath in all the places it leads to some unwanted errors anytime so use has-text
from playwright.sync_api import Playwright, sync_playwright, expect
def run(playwright: Playwright) -> None:
browser = playwright.chromium.launch(headless=False)
context = browser.new_context()
# Open new page
page = context.new_page()
# Go to https://www.pinterest.co.uk/login/
page.goto("https://www.pinterest.co.uk/login/")
# Click [placeholder="Email"]
page.locator("[placeholder=\"Email\"]").click()
# Fill [placeholder="Email"]
page.locator("[placeholder=\"Email\"]").fill("xxxxx#gmail.com")
# Click [placeholder="Password"]
page.locator("[placeholder=\"Password\"]").click()
# Fill [placeholder="Password"]
page.locator("[placeholder=\"Password\"]").fill("password")
# Click button:has-text("Log in")
# with page.expect_navigation(url="https://www.pinterest.co.uk/"):
with page.expect_navigation():
page.locator("button:has-text(\"Log in\")").click()
# ---------------------
context.close()
browser.close()
with sync_playwright() as playwright:
run(playwright)

Python webscraping Selenium fails to navigate page and get data after login

I am using Selenium to automate few checkboxes inside an internal Webportal. I am able to successfully login to the page with credentials using Selenium. But after logging in, if I try to navigate to the required page to get content of Webpage, even the login is not happening. And the page remains in the login page itself without being able to login to Webportal.
Here is the approach which I used:
driver.get('<myLoginURL>')
# maximize window
driver.maximize_window()
# wait for username input, scroll to it, enter username
username = WebDriverWait(driver, DELAY).until(EC.presence_of_element_located((By.ID, "inputUsername")))
driver.execute_script("arguments[0].scrollIntoView();", username)
username.send_keys("<userID>")
...... similarly with password.....And then submit...
submit = WebDriverWait(driver, DELAY).until(EC.element_to_be_clickable((By.CLASS_NAME, "btn")))
driver.execute_script("arguments[0].scrollIntoView();", submit)
submit.click()
WebDriverWait(driver,DELAY)
driver.get("<URL_To be Navigated to>")
# WebDriverWait(driver,DELAY).until(driver.get(desired_URL))
url = driver.current_url
driver.get(url)
source = driver.page_source
Problems occured:
WebPage will not login with login credentials mentioned.
Scraped content gives only login page data (i.e, enter username, enter password)
Can someone suggest me good tutorial how to effectively use Selenium to :
Scrape the data with tags. Currently I am super confused how to use 'EC.presence_of_element_located' and 'find_element_by_ID'
Reach the webpage I desire to scrape after logging in
how to extract data from the page I want
Can anyone suggest me what is the mistake I am doing while navigating the page and get the data
Many thanks in advance

Selenium: How to deal with the situation where being treated as robots

I am using Selenium to simulate login with Chrome browser. The login page has Slider button which needs to be dragged to complete the login process.
The weird thing is that if I open the web page using driver.get(page). Then sliding verification code will always fail even I manually enter the username, pwd and drag the slider.
I tried to add user-agent but no help.
Is there any other way? I understand that we can add user-data to skip this part but I just want to figure it out first.
The slider verification code will display if you try to log in more than once. It seems that the web page just detect you are using the script to log in.
The error will be like:" ops, failed to verify. Please refresh again". Then I use driver.find_element_by_xpath("//*[#id='nocaptcha']/div/span/a").click() to refresh the slider.
Thanks in advance.
driver = webdriver.Chrome()
driver.get("https://login.taobao.com/member/login.jhtml?spm=a21bo.2017.754894437.1.5af911d95pqPfs&f=top&redirectURL=https%3A%2F%2Fwww.taobao.com%2F")
action = ActionChains(driver)
login()
def login():
driver.find_element_by_class_name("login-switch").click()
driver.find_element_by_id('TPL_username_1').clear()
driver.find_element_by_id('TPL_username_1').send_keys('xxx')
driver.find_element_by_id('TPL_password_1').clear()
driver.find_element_by_id('TPL_password_1').send_keys("xxx")
time.sleep(1.5)
# driver.find_element_by_id('J_SubmitStatic').click()
Slider()
def Slider():
#Sliding verification code
while True:
try:
slip=driver.find_element_by_xpath("//*[#id='nc_1_n1z']")
action.click_and_hold(slip).perform()
action.move_by_offset(150,0)
time.sleep(0.8)
action.move_by_offset(148,0)
action.release().perform()
time.sleep(2)
text = driver.find_element_by_xpath("//*[#id='nc_1__scale_text']/span")
if text.text.startswith("请在下方"):
print("Successful")
break
if text.text.startswith("请点击"):
print("Successful")
break
if text.text.startswith("请按住"):
print("Failed. Try again")
continue
except Exception:
##Error occurs, click the "Refresh" button to refresh the sliding verification code again
driver.find_element_by_xpath("//*[#id='nocaptcha']/div/span/a").click()
driver.find_element_by_id('J_SubmitStatic').click()

Selenium webdriver - element can be found but is not visible?

I am working on a personal project to make a python script to log in to a site and do few tasks for me, and I've decided to use the Selenium web driver. Currently I am stuck on the log in part.
driver = webdriver.Chrome()
driver.get("https://pucatrade.com")
puca_username = "example#username"
user_fieldID = "login"
user_fieldelement = driver.find_element_by_id(user_fieldID)
user_fieldelement.send_keys(puca_username)
However, it gives me selenium.common.exceptions.ElementNotVisibleException: Message: element not visible on the send_keys call. I know that find_element_by_id finds the element because I've tested with print user_fieldelement.get_attribute('id'), and it prints login. So if find_element_by_id works can find the element, how come send_keys can't?
There are multiple inputs having id="login". You are interested in the one located in the login form on the very right which is inside the div with id="home-login":
form = driver.find_element_by_id("home-login")
# login
user_fieldelement = form.find_element_by_id(user_fieldID)
user_fieldelement.send_keys(puca_username)
# password
passwd_fieldelement = form.find_element_by_id(passwd_fieldID)
user_fieldelement.send_keys(puca_password)
I'm still not sure why some websites has many fields with same name and id... but as I was only interested on the visible ones, I did this little function to get the right field.
def find_visible_element_by_name(name):
# Websites, for some reason, has many fields with the sama name and ID! This gets the first one that is visible.
# http://stackoverflow.com/questions/32462116/selenium-webdriver-element-can-be-found-but-is-not-visible
fields = self.sel.find_elements_by_name(name)
for f in fields:
if f.is_displayed():
return f
return None
self.sel is the Selenium driver object.

Staying logged in with Selenium in Python

I am trying to log into a website and then once logged in navigate to a different page on the website remaining logged in, using Selenium. However, when I try to navigate to the different page, I found I have become logged off.
I believe this is because I do not understand how the webdriver.Firefox().get() function works exactly.
My code:
from selenium import webdriver
from Code.Other import XMLParser
#Initialise driver and go to webpage
driver = webdriver.Firefox()
URL = 'http://www.website.com'
driver.get(URL)
#Login
UserName = XMLParser.XMLParse('./Config.xml','UserName')
Password = XMLParser.XMLParse('./Config.xml','Password')
element = driver.find_elements_by_id('UserName')
element[0].send_keys(UserName)
element = driver.find_elements_by_id('Password')
element[0].send_keys(Password)
element = driver.find_elements_by_id('Submit')
element[0].click()
#Go to new page
URL = 'http://www.website.com/page1'
driver.get(URL)
Unfortunately I am navigated to the new page but I am no longer logged in. How do I fix this?
Looks like website doesn't have enough time to react on your submit in authorization form. You click submit but you don't wait for response and open another url.
Wait until some event after login (like getting cookies or some changes in DOM or just time.sleep) and only then go to another page.
P.S.: if it won't help, try to check your cookies after login and after you open new url, maybe it's problem with authorization backend or webdriver

Categories