I am trying to learn python and selenium. and I am using pytest-bdd. and there is conftest.py. Normally I defined my driver in this page under before_scenarios method. And I have basepage which contains click,hover_to,text_presents etc some operations. Conftest also use my BasePage click method to close popups. and I have LoginTest.py which use Basepage.
How can I use driver for all pages. because I cant get driver. What is my mistake also could u pls explain?
Here is my code:
conftest.py:
bp = BasePage.BasePage()
def pytest_bdd_before_scenario():
global driver
url="myurl"
logger.info("\nBrowser operations before test running\n")
driver = webdriver.Chrome()
driver.get(url)
driver.maximize_window()
website_is_up_and_running(url)
bp.click((By.XPATH , "//div[#title='Kapat']"))
bp.click((By.XPATH , "//a[#class='close-button']"))
Here is my BasePage:
class BasePage():
def click(self,driver,by_locator):
WebDriverWait(driver, 60) .until(EC.visibility_of_element_located((by_locator))).click()
And Finally, this is my LoginTest.py:
import utilities.BasePage as BasePage
bp = BasePage.BasePage()
#when('I click the Login Button')
def i_click_the_login_button():
bp.hover_to_and_click(driver,(By.XPATH , "(//p[#class='link-text'])[1]")) //in this line I can't get driver.
Related
I'm new to python and selenium. I want to call a login function from another file and then continue my test within the same driver. I've managed to write a login function > call it from the other file but when I continue with my test, i get the following error, NameError: name 'driver' is not defined
How can I make this work so I can reference the login function to login and then continue writing code without getting the NameError?
Here is the code
file1.py
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
def login(context):
s = Service("C:pythonProject/chromedriver.exe")
# Starts the chrome driver
global driver
driver = webdriver.Chrome(service=s)
driver.maximize_window()
def username(context):
# URL
url = "https://www.bbc.com"
driver.get(url)
driver.implicitly_wait(10)
search = driver.find_element(By.ID, "user")
search.send_keys('xxxxx')
search = driver.find_element(By.ID, "pass")
search.send_keys('xxxxx')
driver.find_element(By.ID, "log_in_button").click()
file2.py
from behave import *
from file1 import *
from selenium.webdriver.common.by import By
#given(u'sdsd')
def step_impl(context):
login(context)
username(context)
#when(u'sdds')
def step_impl(context):
search = driver.find_element(By.ID, "headerBar")
Not even from … import * can give you access to names added by global after the import occurs. (Worse still, if they are reassigned, you’ll still have the old value.)
Just take that as yet another reason not to use that syntax: write
import file1
…:
search = file1.driver.find_element(By.ID, "headerBar")
or better yet have the file1 functions return driver rather than storing it in a global at all.
Trying to setup Chrome for the open / close a website. Now i can open it, But failed to close it.
Can anyone tell me why? Many thanks!
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
class chromeSetup():
def __init__(self):
self.chrome_path = r'C:\XXXXX\chromedriver.exe'
def searchWeb(self, url="https://www.google.com.hk/"):
driver = webdriver.Chrome(self.chrome_path)
driver.get(url)
def close(self):
self.driver.close()
You are not making driver an instance attribute. Change searchWeb method like this:
def searchWeb(self, url="https://www.google.com.hk/"):
self.driver = webdriver.Chrome(self.chrome_path)
self.driver.get(url)
I've written below code:
from selenium import webdriver
driver = webdriver.Chrome()
driver.get('https://www.google.co.jp/')
driver.get('https://www.yahoo.com/')
Of course this code just shows the 2nd page, but I want to show both of the pages at the same time. How do I implement it?
You need to use two separate webdriver.Chrome instances:
from selenium import webdriver
driver1 = webdriver.Chrome()
driver2 = webdriver.Chrome()
driver1.get('https://www.google.co.jp/')
driver2.get('https://www.yahoo.com/')
In first file , there is a below code.
I want to use the driver instance of first file in second file , I am able to call it but getting an exception Nosuchelementexception
Basically i want the same browser session in both files , note that import statements are provided properly to use those.
class Init():
driver = webdriver.Chrome(
executable_path="C:\Program Files (x86)\Python36-32\selenium\webdriver\chromedriver_win32\chromedriver.exe")
def take_screenshot(self):
Init.driver.get_screenshot_as_png("Testcase.png")
def browser_launch(self):
Init.driver.set_page_load_timeout(20)
Init.driver.get("http://url/")
Init.driver.maximize_window()
def user_comes_in(self):
Init.driver.find_element_by_id("username").send_keys("admin")
Init.driver.find_element_by_name("password").send_keys("admin")
Init.driver.find_element_by_class_name("Button").click()
Init.driver.set_page_load_timeout(20)
In second file , here is the code
initiate = Init()
class Two(unittest.TestCase):
initiate.browser_launch()
def test_user_logs(self):
initiate.user_comes_in()
print("test case one")
def test_user_create(self):
initiate.user_creation()
print("Test case two")
if you can keep the browser open, you can do it like this:
init.py:
def setDriver():
driver = webdriver.Firefox()
driver.maximize_window()
driver = setDriver()
1.py:
from init.py import driver
driver.get('xxxx')
2.py:
from init.py import driver
driver.get('yyyy')
they will use same driver and same browser.
but if you close the driver in any of the case file, others can't use it again. so it only available in cases don't need to close browser.
I am testing a native iOS app and need to wait for some elements to load in some of my testing. Appium is going too fast on some screens right now.
Can someone please point me to an example of using a WebDriverWait style of waiting for Appium iOS testing? There was a question that was answered for Ruby here: Wait for element to load when testing an iOS app using Appium and Ruby?. Looking for something similar in Python.
The Python client documentation doesn't seem to document the wait functions.
Thanks.
At the top of the test import these.
from appium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
TL/DR is this should work, you may have to change self.driver to just driver in the wait = section depending on how you're doing things. Also, obviously change the By.XPath to whatever locator you're using:
wait = WebDriverWait(self.driver, 20)
currently_waiting_for = wait.until(EC.element_to_be_clickable((By.XPATH,'//UIAApplication[1]/UIAWindow[1]/UIAButton[#text="example text"]')))
Or you could just tell the driver to use implicit waits.
self.driver.implicitly_wait(10)
myElement = driver.find_element_by_id("fakeid")
myElement.click()
Most of this is explained here.
Here's an example of using wait to log into an Android App (Haven't used it on ios but it should be the similar) using the default account selector then asserting the right text appeared. During the setup, I'm loading my desired capabilities from another file.
class TrainUpSmokeTests(unittest.TestCase):
def setUp(self):
desired_caps = desired_capabilities.get_desired_capabilities('app-debug.apk')
self.driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)
def tearDown(self):
self.driver.quit()
def example_test(self):
wd = self.driver
## Depending on how you're running the test the first variable may just be driver. Or in my case self.driver which I shortened above. The number is how many seconds it should wait before timing out.
wait = WebDriverWait(wd, 20)
## Waiting for account selector to be clickable.
currently_waiting_for = wait.until(EC.element_to_be_clickable((By.XPATH,'//android.widget.CheckedTextView[#text="FakeEmail#example.com"]')))
## Locating test account and selecting it.
account = wd.find_element_by_android_uiautomator('text("FakeEmail#example.com")')
account.click()
ok_button = wd.find_element_by_android_uiautomator('text("OK")')
ok_button.click()
## Waiting for an Element on the home screen to be locatable.
currently_waiting_for = wait.until(EC.presence_of_element_located((By.XPATH,'//android.widget.RelativeLayout[#resource-id="com.name.app:id/overview"]')))
hero_headline = wd.find_element_by_android_uiautomator('new UiSelector().description("Example Header")')
self.assertIsNotNone(hero_headline)
if __name__ == '__main__':
suite = unittest.TestLoader().loadTestsFromTestCase(TrainUpSmokeTests)
unittest.TextTestRunner(verbosity=2).run(suite)
It's a your testings a website using appium (instead of an app). Change the setup so self.driver opens a browser.
self.driver = webdriver.Firefox()
And then use By selectors like class, name, id, e.g. the example below.
currently_waiting_for = wait.until(EC.element_to_be_clickable((By.CLASS_NAME,'search-results')))
This article also helped. Also if you don't know how to find xpaths, look into setting up uiautomatorviewer that comes with appium.
The python usage is:
driver.implicitly_wait(timeToWaitSec)
Selenium sourcecode(Py)
You can use WaitForElement class:
class WaitForElement:
#staticmethod
def wait(driver, id, time_out=100):
try:
WebDriverWait(driver, time_out).until(
lambda driver: driver.find_element(*id))
except TimeoutException:
print('Not able to find ID:' + id)
You can find all you need in selenium.webdriver.support.expected_conditions
Then from it you can do something like:
def wait_for_element_visible(self, by=By.XPATH, value=None, text=None, wait_time=20):
if text is not None:
value = value % text
wait = WebDriverWait(self.driver, wait_time)
return wait.until(EC.visibility_of_element_located((by, value)))
You can use implicitWait. Something like remoteWebDriver.implicitlyWait(time, timeUnit) This of course is for java. Something similar should be available for python.