undefined variable 'driver' / don't create new chrome instance - python

I am trying to call a click function, lastly in my /main.py file.
/main.py
"""Start Point"""
from data.find_pending_records import FindPendingRecords
from vital.vital_entry import VitalEntry
import sys
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains
import pandas as pd
if __name__ == "__main__":
try:
# for PENDING_RECORDS in FindPendingRecords().get_excel_data(): begin to loop through entire directory
PENDING_RECORDS = FindPendingRecords().get_excel_data()
# Do operations on PENDING_RECORDS
# Reads excel to map data from excel to vital
MAP_DATA = FindPendingRecords().get_mapping_data()
# Configures Driver
VITAL_ENTRY = VitalEntry()
# Start chrome and navigate to vital website
VITAL_ENTRY.instantiate_chrome()
# Begin processing Records
VITAL_ENTRY.process_records(PENDING_RECORDS, MAP_DATA)
# Save Record
VITAL_ENTRY.save_contact(driver)
print (PENDING_RECORDS)
print("All done")
except Exception as exc:
# print(exc)
raise
/vital_entry.py
class VitalEntry:
"""Vital Entry"""
def save_contact (self, driver):
driver.implicitly_wait(15)
driver.find_element_by_css_selector("#publishButton").click()
I am continuously getting this error in Prompt:
Traceback (most recent call last):
File "main.py", line 32, in <module>
VITAL_ENTRY.save_contact(driver)
NameError: name 'driver' is not defined
I do not want to create a new chrome session or window... I've also tried chaining this on my VITAL_ENTRY.process_records(PENDING_RECORDS, MAP_DATA) above. As you can see I am already importing the driver; and I am using it in the above calls - I don't want to create a new browser instance.
Here is the .instantiate_chrome() below:
def instantiate_chrome(self):
"""Create Chrome webdriver instance."""
self.options.headless = config.HEADLESS
if not self.options.headless:
self.options.add_argument("--start-maximized")
self.options.add_argument('--disable-infobars')
self.options.add_argument('--disable-gpu')
self.driver = webdriver.Chrome(options=self.options)
self.driver.set_page_load_timeout(30)
self.driver.implicitly_wait(15)
self.driver.get(config.VITAL_URL)

So you create the browser session, then you never pass it out of that function. If you want to use it elsewhere, your instantiate_chrome() code will need to return driver, then you'll need to assign it as I stated in my previous comment
driver= VITAL_ENTRY.instantiate_chrome()

Related

Python Selenium TypeError Expect 3 arguments (1given)

I am not able to solve the following issue :
Below is my python-selenium code.
import unittest
import time
import argparse, sys, os
import traceback
from selenium import webdriver
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
class SeleniumTestPack(unittest.TestCase):
driver = webdriver.Firefox()
timeout = 30
def test_all(self):
admin_base_url = args.url
cognito_url = "test.auth.us-west-2.amazoncognito.com"
user_full_name = "test User"
email = "test#test.com"
firstName = "Selenium"
lastName = "User"
try:
self.test_redirect_to_congito_login_page(admin_base_url, cognito_url)
self.delete_geckodriver_log()
except Exception:
self.driver.save_screenshot('exception.png')
self.fail("Exception: %s" % (traceback.format_exc()))
def test_redirect_to_congito_login_page(self, admin_base_url, cognito_url):
print "Test navigating to home page redirects to cognito login page"
self.driver.get(admin_base_url)
self.wait_for_element_loaded(By.ID, "div-forms")
page_url = self.driver.current_url
assert cognito_url in page_url
def wait_for_element_loaded(self, id_type, id_locator):
min_timeout = 2
tries = 0
retry_limit = 13
while tries <= retry_limit:
try:
tries = tries + 1
element_present = EC.presence_of_element_located((id_type, id_locator))
WebDriverWait(self.driver, min_timeout).until(element_present)
break
except Exception:
if tries <= retry_limit:
continue
self.fail("Exception waiting for page to load %s : %s" % (id_locator,traceback.format_exc()))
def delete_geckodriver_log(self):
#running function at the end of all other invocation ensures all test cases have already ran successfully
geckodriverfile="geckodriver.log"
if os.path.isfile(geckodriverfile):
os.remove(geckodriverfile)
else:
print("Error: %s file not found" % geckodriverfile)
#classmethod
def tearDown(self):
# close the browser window
self.driver.quit()
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='test')
parser.add_argument('--url',action='store',dest='url',default=None,help='<Required> url link',required=True)
parser.add_argument('--username',action='store',dest='username',default=None,help='<Required> username',required=True)
parser.add_argument('--password',action='store',dest='password',default=None,help='<Required> password',required=True)
parser.add_argument('unittest_args', nargs='*')
args = parser.parse_args()
sys.argv[1:] = args.unittest_args
unittest.main()
I am running this test using below command.
xvfb-run --server-args="-screen 0, 1280x1024x8" python admin-ui-test.py --url 'http://localhost:8080' --username 'test' --password 'test1234'
Below is my output:
ERROR: test_redirect_to_congito_login_page (__main__.SeleniumTestPack) TypeError: test_redirect_to_congito_login_page() takes exactly 3 arguments (1 given)
Anything wrong i am doing? I have similar kind of tests at other places as well, Which are working fine since long time.
Any help will be highly appreciated.
The solution is very much new to me.
The function name should not start with "test_" (Otherwise it will be consider as a separate Test Case)
I renamed the function name and it is working fine!

Why the selenium+python code can run line by line in terminal instead of in a whole file format?

import time,os
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains
driver = webdriver.Chrome()
target = "https://pan.baidu.com/"
driver.get(target)
name='name'
passwd='passwd'
driver.find_element_by_xpath('//div[#class="account-title"]/a').click()
driver.find_element_by_xpath('//input[#id="TANGRAM__PSP_4__userName"]').send_keys(name)
driver.find_element_by_xpath('//input[#id="TANGRAM__PSP_4__password"]').send_keys(passwd)
driver.find_element_by_xpath('//input[#id="TANGRAM__PSP_4__submit"]').click()
try:
path1 = driver.find_element_by_xpath('//a[#title="test1"]')
ActionChains(driver).move_to_element(path1).perform()
ActionChains(driver).context_click(path1).perform()
driver.find_element_by_xpath('//*[#class="context-menu"]/ul/li[21]').click()
time.sleep(5)
driver.find_element_by_xpath('//*[#class="g-button g-button-blue-large"]/span/span').click()
time.sleep(5)
except:
pass
try:
path2 = driver.find_element_by_xpath('//a[#title="test2"]')
ActionChains(driver).move_to_element(path2).perform()
ActionChains(driver).context_click(path2).perform()
driver.find_element_by_xpath('//*[#class="context-menu"]/ul/li[21]').click()
time.sleep(5)
driver.find_element_by_xpath('//*[#class="g-button g-button-blue-large"]/span/span').click()
time.sleep(5)
except:
pass
The above code snippet run successfully line by line in python3 terminal,
to input several lines everytime into python3 terminal,do three task for me.
1.automatically login to pan.baidu.com
2.to delete file named test1
3.to delete file named test2
Then to save the above code snippet as up.py and run it with time python3 up.py.
A very interesting thing happen.
1.running time
time python3 up.py
real 0m4.231s
user 0m0.192s
sys 0m0.080s
Why the running time is less then 20 seconds?
2.the third task haven't done
The file named test2 still there ,not deleted by program.
How to explain the strange issues and fix it?
To add a important line:
driver.implicitly_wait(20)

Selenium2Library code completion in PyCharm

I'm experimenting with creating a basic library extension for Robot Framework using Python, and I'm using PyCharm as the editor. For libraries imported directly code completion is working fine, but in this case I'm importing the Selenium2Library indirectly via a method:
def get_current_browser():
browser = BuiltIn().get_library_instance('Selenium2Library')._current_browser()
return browser
Which I call from other methods with something like
driver = get_current_browser()
This successfully grabs the webdriver browser instance from Robot Framework and lets me do as I please, but I don't get code hints when I go to edit a 'driver' variable. Is there way I can get hints in this scenario?
Here's the code in full:
from robot.libraries.BuiltIn import BuiltIn
from Selenium2Library.keywords.keywordgroup import KeywordGroup
import logging
def get_current_browser():
browser = BuiltIn().get_library_instance('Selenium2Library')._current_browser()
return browser
class MyLibrary(KeywordGroup):
def get_title_via_python(self):
driver = get_current_browser()
title = driver.title
logging.warn("checking title %s" % title)
return title
Try adding a docstring to your function to help PyCharm.
from selenium.webdriver import Remote # Remote imported only for code completion
def get_current_browser():
"""
:rtype: Remote
"""
browser = BuiltIn().get_library_instance('Selenium2Library')._current_browser()
return browser
More at http://www.jetbrains.com/pycharm/webhelp/type-hinting-in-pycharm.html

How to pass python object from one file module to another file module?

I am trying to implement page object model in python and selenium. For that matter, I have two modules:
LoginPage.py
class LoginPage:
def __init__(self, driver):
self.driver = driver
'''do something with the self.driver object.
Example: Using self.driver.title() I can make sure if I am on the right page but it shows an error'''
def Login(self, username, password):
'''Use the same driver object for calling username and password objects of a page'''
Program.py
from selenium import webdriver
from LoginPage import *
class Program:
driver = webdriver.Firefox()
driver.get("https://www.linkedin.com/uas/login")
#While creating LoginPage object, I'm passing driver object which is actually a firefox instance.
login = LoginPage(driver)
homePage = login.Login("sample#gmail.com", "mypassword")
if homePage is not None:
print "In Home page"
From the Program.py module, I am creating a Firefox driver and passing the reference to 'driver'. This 'driver' is passed as a parameter to LoginPage().
The LoginPage.py is not able to make use of 'driver'. Can anyone help me find the mistake here?
Traceback:
Traceback (most recent call last):
File "/media/Pinku/POMProject/src/Program.py", line 4, in <module> class Program:
File "/media/Pinku/POMProject/src/Program.py", line 11, in Program login = LoginPage(driver)
File "/media/Pinku/POMProject/src/LoginPage.py", line 5, in init if self.driver.title() == "Sign In":
TypeError: 'unicode' object is not callable
Right I see your problem:
It's very simple, in your __init__ in LoginPage you are calling self.driver.title() however, as per the basic selenium example on their page, it is just self.driver.title (without the brackets).
title is an attribute rather than a callable method, hence the error.

Bad status line exception while opening a page on django development server

I am executing selenium test cases via Proboscis, for good reporting of test results. I have the following test case written
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from proboscis import test
import unittest
driver = webdriver.Firefox()
#test(groups=["unit","login"])
class UI_test(unittest.TestCase):
def test_SuccessfulErrorMsgOnEmptyUserName(self):
driver.get("http://127.0.0.1:7999/login/")
username_input = driver.find_element_by_id("id_email")
username_input.send_keys('')
password_input = driver.find_element_by_id("id_password")
password_input.send_keys('bill3')
driver.find_element_by_xpath('//input[#value = "Log In"]').click()
driver.implicitly_wait(3)
driver.find_element_by_class_name("error-login")
driver.close()
def run_tests():
from proboscis import TestProgram
# from tests import unit
# Run Proboscis and exit.
TestProgram().run_and_exit()
if __name__ == '__main__':
run_tests()
What could be causing the BadStatusLine exception in this code?
Looks like a duplicate of Python/Django "BadStatusLine" error but i can't flag due to this question having a bounty. According to this answer, a BadStatusLine exception is likely caused by an empty response, as in there being no status line at all.
According to this answer, the server formally tells the client there is no more data, instead of simply causing a connection reset or rude timeout.

Categories

Resources