简体   繁体   中英

Create a base driver class and inherit webdriver

In Python/Selenium, I am trying to create a browser class mainly so I can create custom functions like click or type, etc and easily call these by typing something simple such as browser.click(element) or browser.type_text(element, text) .

I think I am sort of on the right track but I cannot get the inheritance to work. For example, when I create a browser instance with browser = Browser() and try to use the normal functions of webdriver like browser.get(webpage) , I get an error stating that there is no GET function. Am I on the right track here? Is there a better way?

class Browser(webdriver.Chrome):
    def __init__():
        super(self).init()
        self.browser = webdriver.Chrome()

    def click(element):
        WebDriverWait(self, 10).until(EC.element_to_be_clickable(element)).click()

browser = Browser()
element = (By.ID, elements['remember'])
browser.click(element)

Update: So it looks like I was able to figure out what I was originally intending to do.

I wanted to create a webdriver using a class and basically extend that library to include some custom functions. I'll explain.

class Browser(webdriver.Chrome):
    def __init__(self):
        super().__init__()

    def click(self, element):
        WebDriverWait(self, 10).until(EC.element_to_be_clickable(element)).click()

    def type(self, element, text):
        for i in text:
            WebDriverWait(browser, 10).until(EC.visibility_of_element_located(element)).send_keys(i)
            time.sleep(random.uniform(0.05,0.25))

So basically here I just added a custom click and type function to make it more convenient to have the webdriver wait for an element and click or type, etc.

browser = Browser()
browser.click(element)
browser.type(element, text)

As @Guy has mentioned, your confusing the functionality of the WebDriver class and the WebElement class. The WebDriver class indeed has methods like get for URL navigation, but the WebElement class has methods like click , and so on. Rather than using your current approach, I recommend a design pattern that's popularly with Selenium: the Page Object Model design pattern .

Following this design pattern will allow you to easily call much simpler method names. For example, taken straight from the linked page:

from element import BasePageElement
from locators import MainPageLocators

class SearchTextElement(BasePageElement):
    """This class gets the search text from the specified locator"""

    #The locator for search box where search string is entered
    locator = 'q'


class BasePage(object):
    """Base class to initialize the base page that will be called from all pages"""

    def __init__(self, driver):
        self.driver = driver


class MainPage(BasePage):
    """Home page action methods come here. I.e. Python.org"""

    #Declares a variable that will contain the retrieved text
    search_text_element = SearchTextElement()

    def is_title_matches(self):
        """Verifies that the hardcoded text "Python" appears in page title"""
        return "Python" in self.driver.title

    def click_go_button(self):
        """Triggers the search"""
        element = self.driver.find_element(*MainPageLocators.GO_BUTTON)
        element.click()


class SearchResultsPage(BasePage):
    """Search results page action methods come here"""

    def is_results_found(self):
        # Probably should search for this text in the specific page
        # element, but as for now it works fine
        return "No results found." not in self.driver.page_source

This will allow you to make simply-named method calls:

MainPage.click_go_button()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM