Exemple #1
0
def do_and_ignore(lambda_func):
    """
    Perform the given function, but only log the error that's printed out.
    Use this function to wrap method calls you would normally do in a try/raise 
    block, but do not care about the results.
    
    Args:
        lambda_func (function) : Lambda function to execute.
    
    Returns:
        Returns same return as the lambda statement.  Otherwise returns None
    
    Usage::

        do_and_ignore(lambda: driver.find_element_by_id("logoutButton").click())
        
    is equivalent to::
        
        try:
            driver.find_element_by_id("logoutButton").click()
        except Exception as e:
            print e
    
    This function is useful for wrapping cleanup calls, since it'll ignore any errors 
    and keeps the test moving along.

    """
    try:
        return lambda_func()
    except Exception as e:
        try:
            print e
        except:
            _wtflog.debug("unknown error")
        return None
Exemple #2
0
def do_and_ignore(lambda_func):
    """
    Perform the given function, but only log the error that's printed out.
    Use this function to wrap method calls you would normally do in a try/raise 
    block, but do not care about the results.

    Args:
        lambda_func (function) : Lambda function to execute.

    Returns:
        Returns same return as the lambda statement.  Otherwise returns None

    Usage::

        do_and_ignore(lambda: driver.find_element_by_id("logoutButton").click())

    is equivalent to::

        try:
            driver.find_element_by_id("logoutButton").click()
        except Exception as e:
            print e

    This function is useful for wrapping cleanup calls, since it'll ignore any errors 
    and keeps the test moving along.

    """
    try:
        return lambda_func()
    except Exception as e:
        try:
            print e
        except:
            _wtflog.debug("unknown error")
        return None
Exemple #3
0
 def __del__(self):
     "Destructor - disconnect from imap when we're done."
     try:
         # Disconnect email.
         self._mail.logout()
     except Exception as e:
         _wtflog.debug(e)
     self._mail = None
Exemple #4
0
 def __del__(self):
     "Destructor - disconnect from imap when we're done."
     try:
         # Disconnect email.
         self._mail.logout()
     except Exception as e:
         _wtflog.debug(e)
     self._mail = None
Exemple #5
0
 def __load_config_file(self, file_name):
     try:
         config_file_location = os.path.join(ProjectUtils.get_project_root(),
                                             ConfigReader.CONFIG_LOCATION,
                                             file_name + ConfigReader.CONFIG_EXT)
         _wtflog.debug(u("locating config file: %s"), config_file_location)
         config_yaml = open(config_file_location, 'r')
         dataMap = yaml.load(config_yaml)
         self._dataMaps.insert(0, dataMap)
         config_yaml.close()
     except Exception as e:
         _wtflog.error(u("Error loading config file: %s"), file_name)
         raise ConfigFileReadError(u("Error reading config file ") + file_name, e)
Exemple #6
0
 def __load_config_file(self, file_name):
     try:
         config_file_location = os.path.join(
             ProjectUtils.get_project_root(), ConfigReader.CONFIG_LOCATION,
             file_name + ConfigReader.CONFIG_EXT)
         _wtflog.debug(u("locating config file: %s"), config_file_location)
         config_yaml = open(config_file_location, 'r')
         dataMap = yaml.load(config_yaml)
         self._dataMaps.insert(0, dataMap)
         config_yaml.close()
     except Exception as e:
         _wtflog.error(u("Error loading config file: %s"), file_name)
         raise ConfigFileReadError(
             u("Error reading config file ") + file_name, e)
Exemple #7
0
    def __init__(self, webdriver, *args, **kwargs):
        """Constructor.  It's better to not call this directly, instead use PageFactory 
        to instantiate PageObjects.

        Args: 
            webdriver (Webdriver): Selenium Webdriver instance.

        """
        try:
            config_reader = kwargs['config_reader']
        except KeyError:
            config_reader = WTF_CONFIG_READER

        try:
            self._validate_page(webdriver)
        except TypeError as e:
            _wtflog.error(
                "PageObjects need to implement '_validate_page(self, webdriver)' method: %s",
                e)
            raise e
        except Exception as e:
            _wtflog.debug("Unable to instantiate page: %s", e)
            raise e

        # Assign webdriver to PageObject.
        # Each page object has an instance of "webdriver" referencing the webdriver
        # driving this page.
        self.webdriver = webdriver

        # Take reference screenshots if this option is enabled.
        if config_reader.get("selenium.take_reference_screenshot",
                             False) == True:
            class_name = type(self).__name__
            if class_name in PageObject.__names_of_classes_we_already_took_screen_caps_of__:
                pass
            else:
                try:
                    WebScreenShotUtil.take_reference_screenshot(
                        webdriver, class_name)
                    PageObject.__names_of_classes_we_already_took_screen_caps_of__[
                        class_name] = True
                except Exception as e:
                    # Some WebDrivers such as head-less drivers does not take
                    # screenshots.
                    _wtflog.error(e)
        else:
            pass
Exemple #8
0
 def clean_up_webdrivers(self):
     '''
     Clean up webdrivers created during execution.
     '''
     # Quit webdrivers.
     _wtflog.info("WebdriverManager : Cleaning up webdrivers")
     try:
         if self.__use_shutdown_hook:
             for key in self.__registered_drivers.keys():
                 for driver in self.__registered_drivers[key]:
                     try:
                         _wtflog.debug("Closing webdriver for thread: %s", key)
                         driver.quit()
                     except:
                         pass
     except:
         pass
Exemple #9
0
 def clean_up_webdrivers(self):
     '''
     Clean up webdrivers created during execution.
     '''
     # Quit webdrivers.
     _wtflog.info("WebdriverManager: Cleaning up webdrivers")
     try:
         if self.__use_shutdown_hook:
             for key in self.__registered_drivers.keys():
                 for driver in self.__registered_drivers[key]:
                     try:
                         _wtflog.debug(
                             "Shutdown hook closing Webdriver for thread: %s", key)
                         driver.quit()
                     except:
                         pass
     except:
         pass
Exemple #10
0
    def __init__(self, webdriver, *args, **kwargs):
        """Constructor.  It's better to not call this directly, instead use PageFactory 
        to instantiate PageObjects.

        Args: 
            webdriver (Webdriver): Selenium Webdriver instance.

        """
        try:
            config_reader = kwargs['config_reader']
        except KeyError:
            config_reader = WTF_CONFIG_READER

        try:
            self._validate_page(webdriver)
        except TypeError as e:
            _wtflog.error("PageObjects need to implement '_validate_page(self, webdriver)' method: %s", e)
            raise e
        except Exception as e:
            _wtflog.debug("Unable to instantiate page: %s", e)
            raise e

        # Assign webdriver to PageObject.
        # Each page object has an instance of "webdriver" referencing the webdriver
        # driving this page.
        self.webdriver = webdriver

        # Take reference screenshots if this option is enabled.
        if config_reader.get("selenium.take_reference_screenshot", False) == True:
            class_name = type(self).__name__
            if class_name in PageObject.__names_of_classes_we_already_took_screen_caps_of__:
                pass
            else:
                try:
                    WebScreenShotUtil.take_reference_screenshot(
                        webdriver, class_name)
                    PageObject.__names_of_classes_we_already_took_screen_caps_of__[
                        class_name] = True
                except Exception as e:
                    # Some WebDrivers such as head-less drivers does not take
                    # screenshots.
                    _wtflog.error(e)
        else:
            pass
Exemple #11
0
    def wait_until_page_loaded(page_obj_class,
                               webdriver=None,
                               timeout=WTF_TIMEOUT_MANAGER.NORMAL,
                               sleep=0.5,
                               bad_page_classes=[],
                               message=None,
                               **kwargs):
        """
        Waits until the page is loaded.

        Args:
            page_obj_class (Class) : PageObject class

        Kwargs:
            webdriver (Webdriver) : Selenium Webdriver.  Default uses WTF_WEBDRIVER_MANAGER's instance.
            timeout (number) : Number of seconds to wait to allow the page to load.
            sleep (number) : Number of seconds to wait between polling.
            bad_page_classes (list) : List of PageObject classes to fail if matched.  For example, ServerError page.
            message (string) : Use your own message with PageLoadTimeoutError raised.

        Returns:
            PageObject

        Raises:
            PageUtilOperationTimeoutError : Timeout occurred before the desired PageObject was matched.
            BadPageEncounteredError : One or more of the PageObject in the specified 'bad_page_classes' list 
            was matched.


        Usage Example:: 
            webdriver.get("http://www.mysite.com/login")
            # Wait up to 60 seconds for the page to load.
            login_page = wait_until_page_loaded(LoginPage, timeout=60, [ServerErrorPage])

        This will wait for the login_page to load, then return a LoginPage() PageObject.

        """
        if not webdriver:
            webdriver = WTF_WEBDRIVER_MANAGER.get_driver()

        # convert this param to list if not already.
        if type(bad_page_classes) != list:
            bad_page_classes = [bad_page_classes]

        end_time = datetime.now() + timedelta(seconds=timeout)
        last_exception = None
        while datetime.now() < end_time:
            # Check to see if we're at our target page.
            try:
                page = PageFactory.create_page(
                    page_obj_class, webdriver=webdriver, **kwargs)
                return page
            except Exception as e:
                _wtflog.debug("Encountered exception: %s ", e)
                last_exception = e

            # Check to see if we're at one of those labled 'Bad' pages.
            for bad_page_class in bad_page_classes:
                try:
                    PageFactory.create_page(
                        bad_page_class, webdriver=webdriver, **kwargs)
                    # if the if/else statement succeeds, than we have an error.
                    raise BadPageEncounteredError(
                        u("Encountered a bad page. ") + bad_page_class.__name__)
                except BadPageEncounteredError as e:
                    raise e
                except:
                    pass  # We didn't hit a bad page class yet.
            # sleep till the next iteration.
            time.sleep(sleep)

        print "Unable to construct page, last exception", last_exception

        # Attempt to get current URL to assist in debugging
        try:
            current_url = webdriver.current_url
        except:
            # unable to get current URL, could be a webdriver for a non-webpage like mobile app.
            current_url = None

        if message:
            err_msg = u(message) + u("{page}:{url}")\
                .format(page=PageUtils.__get_name_for_class__(page_obj_class),
                        url=current_url)
        else:
            err_msg = u("Timed out while waiting for {page} to load. Url:{url}")\
                .format(page=PageUtils.__get_name_for_class__(page_obj_class),
                        url=current_url)
        raise PageLoadTimeoutError(err_msg)
Exemple #12
0
    def create_page(page_object_class_or_interface,
                    webdriver=None, **kwargs):
        """
        Instantiate a page object from a given Interface or Abstract class.

        Args:
            page_object_class_or_interface (Class): PageObject class, AbstractBaseClass, or 
            Interface to attempt to consturct.

        Kwargs:
            webdriver (WebDriver): Selenium Webdriver to use to instantiate the page. If none 
                                   is provided, then it was use the default from 
                                   WTF_WEBDRIVER_MANAGER

        Returns:
            PageObject

        Raises:
            NoMatchingPageError

        Instantiating a Page from PageObject from class usage::

            my_page_instance = PageFactory.create_page(MyPageClass)


        Instantiating a Page from an Interface or base class::

            import pages.mysite.*  # Make sure you import classes first, or else PageFactory will not know about it.
            my_page_instance = PageFactory.create_page(MyPageInterfaceClass)


        Instantiating a Page from a list of classes.::

            my_page_instance = PageFactory.create_page([PossiblePage1, PossiblePage2])


        Note: It'll only be able to detect pages that are imported.  To it's best to 
        do an import of all pages implementing a base class or the interface inside the 
        __init__.py of the package directory.  

        """
        if not webdriver:
            webdriver = WTF_WEBDRIVER_MANAGER.get_driver()

        # will be used later when tracking best matched page.
        current_matched_page = None

        # used to track if there is a valid page object within the set of PageObjects searched.
        was_validate_called = False

        # Walk through all classes if a list was passed.
        if type(page_object_class_or_interface) == list:
            subclasses = []
            for page_class in page_object_class_or_interface:
                # attempt to instantiate class.
                page = PageFactory.__instantiate_page_object(page_class,
                                                             webdriver,
                                                             **kwargs)

                if isinstance(page, PageObject):
                    was_validate_called = True
                    if (current_matched_page == None or page > current_matched_page):
                        current_matched_page = page

                elif page is True:
                    was_validate_called = True

                # check for subclasses
                subclasses += PageFactory.__itersubclasses(page_class)
        else:
            # A single class was passed in, try to instantiate the class.
            page_class = page_object_class_or_interface
            page = PageFactory.__instantiate_page_object(page_class,
                                                         webdriver,
                                                         **kwargs)
            # Check if we got a valid PageObject back.
            if isinstance(page, PageObject):
                was_validate_called = True
                current_matched_page = page
            elif page is True:
                was_validate_called = True

            # check for subclasses
            subclasses = PageFactory.__itersubclasses(
                page_object_class_or_interface)

        # Iterate over subclasses of the passed in classes to see if we have a
        # better match.
        for pageClass in subclasses:
            try:
                page = PageFactory.__instantiate_page_object(pageClass,
                                                      webdriver,
                                                      **kwargs)
                # If we get a valid PageObject match, check to see if the ranking is higher
                # than our current PageObject.
                if isinstance(page, PageObject):
                    was_validate_called = True
                    if current_matched_page == None or page > current_matched_page:
                        current_matched_page = page
                elif page is True:
                    was_validate_called = True

            except InvalidPageError as e:
                _wtflog.debug("InvalidPageError: %s", e)
                pass  # This happens when the page fails check.
            except TypeError as e:
                _wtflog.debug("TypeError: %s", e)
                # this happens when it tries to instantiate the original
                # abstract class.
                pass
            except Exception as e:
                _wtflog.debug("Exception during page instantiation: %s", e)
                # Unexpected exception.
                raise e

        # If no matching classes.
        if not isinstance(current_matched_page, PageObject):
            # Check that there is at least 1 valid page object that was passed in.
            if was_validate_called is False:
                raise TypeError("Neither the PageObjects nor it's subclasses have implemented " + 
                                "'PageObject._validate(self, webdriver)'.")

            try:
                current_url = webdriver.current_url
                raise NoMatchingPageError(u("There's, no matching classes to this page. URL:{0}")
                                          .format(current_url))
            except:
                raise NoMatchingPageError(u("There's, no matching classes to this page. "))
        else:
            return current_matched_page
Exemple #13
0
    def wait_until_page_loaded(page_obj_class,
                               webdriver=None,
                               timeout=WTF_TIMEOUT_MANAGER.NORMAL,
                               sleep=0.5,
                               bad_page_classes=[],
                               message=None,
                               **kwargs):
        """
        Waits until the page is loaded.

        Args:
            page_obj_class (Class) : PageObject class

        Kwargs:
            webdriver (Webdriver) : Selenium Webdriver.  Default uses WTF_WEBDRIVER_MANAGER's instance.
            timeout (number) : Number of seconds to wait to allow the page to load.
            sleep (number) : Number of seconds to wait between polling.
            bad_page_classes (list) : List of PageObject classes to fail if matched.  For example, ServerError page.
            message (string) : Use your own message with PageLoadTimeoutError raised.

        Returns:
            PageObject

        Raises:
            PageUtilOperationTimeoutError : Timeout occurred before the desired PageObject was matched.
            BadPageEncounteredError : One or more of the PageObject in the specified 'bad_page_classes' list 
            was matched.


        Usage Example:: 
            webdriver.get("http://www.mysite.com/login")
            # Wait up to 60 seconds for the page to load.
            login_page = wait_until_page_loaded(LoginPage, timeout=60, [ServerErrorPage])

        This will wait for the login_page to load, then return a LoginPage() PageObject.

        """
        if not webdriver:
            webdriver = WTF_WEBDRIVER_MANAGER.get_driver()

        # convert this param to list if not already.
        if type(bad_page_classes) != list:
            bad_page_classes = [bad_page_classes]

        end_time = datetime.now() + timedelta(seconds=timeout)
        last_exception = None
        while datetime.now() < end_time:
            # Check to see if we're at our target page.
            try:
                page = PageFactory.create_page(page_obj_class,
                                               webdriver=webdriver,
                                               **kwargs)
                return page
            except Exception as e:
                _wtflog.debug("Encountered exception: %s ", e)
                last_exception = e

            # Check to see if we're at one of those labled 'Bad' pages.
            for bad_page_class in bad_page_classes:
                try:
                    PageFactory.create_page(bad_page_class,
                                            webdriver=webdriver,
                                            **kwargs)
                    # if the if/else statement succeeds, than we have an error.
                    raise BadPageEncounteredError(
                        u("Encountered a bad page. ") +
                        bad_page_class.__name__)
                except BadPageEncounteredError as e:
                    raise e
                except:
                    pass  # We didn't hit a bad page class yet.
            # sleep till the next iteration.
            time.sleep(sleep)

        print "Unable to construct page, last exception", last_exception

        # Attempt to get current URL to assist in debugging
        try:
            current_url = webdriver.current_url
        except:
            # unable to get current URL, could be a webdriver for a non-webpage like mobile app.
            current_url = None

        if message:
            err_msg = u(message) + u("{page}:{url}")\
                .format(page=PageUtils.__get_name_for_class__(page_obj_class),
                        url=current_url)
        else:
            err_msg = u("Timed out while waiting for {page} to load. Url:{url}")\
                .format(page=PageUtils.__get_name_for_class__(page_obj_class),
                        url=current_url)
        raise PageLoadTimeoutError(err_msg)
Exemple #14
0
    def create_page(page_object_class_or_interface, webdriver=None, **kwargs):
        """
        Instantiate a page object from a given Interface or Abstract class.

        Args:
            page_object_class_or_interface (Class): PageObject class, AbstractBaseClass, or 
            Interface to attempt to consturct.

        Kwargs:
            webdriver (WebDriver): Selenium Webdriver to use to instantiate the page. If none 
                                   is provided, then it was use the default from 
                                   WTF_WEBDRIVER_MANAGER

        Returns:
            PageObject

        Raises:
            NoMatchingPageError

        Instantiating a Page from PageObject from class usage::

            my_page_instance = PageFactory.create_page(MyPageClass)


        Instantiating a Page from an Interface or base class::

            import pages.mysite.*  # Make sure you import classes first, or else PageFactory will not know about it.
            my_page_instance = PageFactory.create_page(MyPageInterfaceClass)


        Instantiating a Page from a list of classes.::

            my_page_instance = PageFactory.create_page([PossiblePage1, PossiblePage2])


        Note: It'll only be able to detect pages that are imported.  To it's best to 
        do an import of all pages implementing a base class or the interface inside the 
        __init__.py of the package directory.  

        """
        if not webdriver:
            webdriver = WTF_WEBDRIVER_MANAGER.get_driver()

        # will be used later when tracking best matched page.
        current_matched_page = None

        # used to track if there is a valid page object within the set of PageObjects searched.
        was_validate_called = False

        # Walk through all classes if a list was passed.
        if type(page_object_class_or_interface) == list:
            subclasses = []
            for page_class in page_object_class_or_interface:
                # attempt to instantiate class.
                page = PageFactory.__instantiate_page_object(
                    page_class, webdriver, **kwargs)

                if isinstance(page, PageObject):
                    was_validate_called = True
                    if (current_matched_page == None
                            or page > current_matched_page):
                        current_matched_page = page

                elif page is True:
                    was_validate_called = True

                # check for subclasses
                subclasses += PageFactory.__itersubclasses(page_class)
        else:
            # A single class was passed in, try to instantiate the class.
            page_class = page_object_class_or_interface
            page = PageFactory.__instantiate_page_object(
                page_class, webdriver, **kwargs)
            # Check if we got a valid PageObject back.
            if isinstance(page, PageObject):
                was_validate_called = True
                current_matched_page = page
            elif page is True:
                was_validate_called = True

            # check for subclasses
            subclasses = PageFactory.__itersubclasses(
                page_object_class_or_interface)

        # Iterate over subclasses of the passed in classes to see if we have a
        # better match.
        for pageClass in subclasses:
            try:
                page = PageFactory.__instantiate_page_object(
                    pageClass, webdriver, **kwargs)
                # If we get a valid PageObject match, check to see if the ranking is higher
                # than our current PageObject.
                if isinstance(page, PageObject):
                    was_validate_called = True
                    if current_matched_page == None or page > current_matched_page:
                        current_matched_page = page
                elif page is True:
                    was_validate_called = True

            except InvalidPageError as e:
                _wtflog.debug("InvalidPageError: %s", e)
                pass  # This happens when the page fails check.
            except TypeError as e:
                _wtflog.debug("TypeError: %s", e)
                # this happens when it tries to instantiate the original
                # abstract class.
                pass
            except Exception as e:
                _wtflog.debug("Exception during page instantiation: %s", e)
                # Unexpected exception.
                raise e

        # If no matching classes.
        if not isinstance(current_matched_page, PageObject):
            # Check that there is at least 1 valid page object that was passed in.
            if was_validate_called is False:
                raise TypeError(
                    "Neither the PageObjects nor it's subclasses have implemented "
                    + "'PageObject._validate(self, webdriver)'.")

            try:
                current_url = webdriver.current_url
                raise NoMatchingPageError(
                    u("There's, no matching classes to this page. URL:{0}").
                    format(current_url))
            except:
                raise NoMatchingPageError(
                    u("There's, no matching classes to this page. "))
        else:
            return current_matched_page
Exemple #15
0
    def create_page(page_object_class_or_interface, \
                    webdriver=None, **kwargs):
        """
        Instantiate a page object from a given Interface or Abstract class.

        Args:
            page_object_class_or_interface (Class): PageObject class, AbstractBaseClass, or 
            Interface to attempt to consturct.
        
        Kwargs:
            webdriver (WebDriver): Selenium Webdriver to use to instantiate the page.
        
        Returns:
            PageObject
        
        Raises:
            NoMatchingPageError
        
        Instantiating a Page from PageObject from class usage::
        
            my_page_instance = PageFactory.create_page(MyPageClass)
            
        
        Instantiating a Page from an Interface or base class::
        
            import pages.mysite.*  # Make sure you import classes first, or else PageFactory will not know about it.
            my_page_instance = PageFactory.create_page(MyPageInterfaceClass)
            
        
        Instantiating a Page from a list of classes.::
        
            my_page_instance = PageFactory.create_page([PossiblePage1, PossiblePage2])
            
        
        Note: It'll only be able to detect pages that are imported.  To it's best to 
        do an import of all pages implementing a base class or the interface inside the 
        __init__.py of the package directory.  
        
        """
        
        if not webdriver:
            webdriver = WTF_WEBDRIVER_MANAGER.get_driver()
        
        # will be used later when tracking best matched page.
        current_matched_page = None
        
        
        # Walk through all classes of this sub class 
        if type(page_object_class_or_interface) == list:
            subclasses = []
            for page_class in page_object_class_or_interface:
                # attempt to instantiate class.
                page = PageFactory.__instantiate_page_object(page_class, \
                                                             webdriver, \
                                                             **kwargs)
                if isinstance(page, PageObject) and (current_matched_page == None or page > current_matched_page):
                    current_matched_page = page
                
                # check for subclasses
                subclasses += PageFactory.__itersubclasses(page_class)
        else:
            # Try the original class
            page_class = page_object_class_or_interface
            page = PageFactory.__instantiate_page_object(page_class, \
                                                         webdriver, \
                                                         **kwargs)
            if isinstance(page, PageObject):
                current_matched_page = page

            # check for subclasses
            subclasses = PageFactory.__itersubclasses(page_object_class_or_interface)

        # Iterate over subclasses of the passed in classes to see if we have a better match.
        for pageClass in subclasses :
            try:
                page = pageClass(webdriver, **kwargs)
                if current_matched_page == None or page > current_matched_page:
                    current_matched_page = page
            except InvalidPageError as e:
                _wtflog.debug("InvalidPageError: %s", e)
                pass  # This happens when the page fails check.
            except TypeError as e:
                _wtflog.debug("TypeError: %s", e)
                pass  # this happens when it tries to instantiate the original abstract class.
            except Exception as e:
                _wtflog.debug("Exception: %s", e)
                # Unexpected exception.
                raise e

        # If no matching classes.
        if not isinstance(current_matched_page, PageObject):
            raise NoMatchingPageError(u("There's, no matching classes to this page. URL:{0}") \
                                      .format(webdriver.current_url))
        else:
            return current_matched_page
Exemple #16
0
    def create_page(page_object_class_or_interface, webdriver=None, **kwargs):
        """
        Instantiate a page object from a given Interface or Abstract class.

        Args:
            page_object_class_or_interface (Class): PageObject class, AbstractBaseClass, or 
            Interface to attempt to consturct.

        Kwargs:
            webdriver (WebDriver): Selenium Webdriver to use to instantiate the page.

        Returns:
            PageObject

        Raises:
            NoMatchingPageError

        Instantiating a Page from PageObject from class usage::

            my_page_instance = PageFactory.create_page(MyPageClass)


        Instantiating a Page from an Interface or base class::

            import pages.mysite.*  # Make sure you import classes first, or else PageFactory will not know about it.
            my_page_instance = PageFactory.create_page(MyPageInterfaceClass)


        Instantiating a Page from a list of classes.::

            my_page_instance = PageFactory.create_page([PossiblePage1, PossiblePage2])


        Note: It'll only be able to detect pages that are imported.  To it's best to 
        do an import of all pages implementing a base class or the interface inside the 
        __init__.py of the package directory.  

        """

        if not webdriver:
            webdriver = WTF_WEBDRIVER_MANAGER.get_driver()

        # will be used later when tracking best matched page.
        current_matched_page = None

        # Walk through all classes of this sub class
        if type(page_object_class_or_interface) == list:
            subclasses = []
            for page_class in page_object_class_or_interface:
                # attempt to instantiate class.
                page = PageFactory.__instantiate_page_object(
                    page_class, webdriver, **kwargs)
                if isinstance(page,
                              PageObject) and (current_matched_page == None
                                               or page > current_matched_page):
                    current_matched_page = page

                # check for subclasses
                subclasses += PageFactory.__itersubclasses(page_class)
        else:
            # Try the original class
            page_class = page_object_class_or_interface
            page = PageFactory.__instantiate_page_object(
                page_class, webdriver, **kwargs)
            if isinstance(page, PageObject):
                current_matched_page = page

            # check for subclasses
            subclasses = PageFactory.__itersubclasses(
                page_object_class_or_interface)

        # Iterate over subclasses of the passed in classes to see if we have a
        # better match.
        for pageClass in subclasses:
            try:
                page = pageClass(webdriver, **kwargs)
                if current_matched_page == None or page > current_matched_page:
                    current_matched_page = page
            except InvalidPageError as e:
                _wtflog.debug("InvalidPageError: %s", e)
                pass  # This happens when the page fails check.
            except TypeError as e:
                _wtflog.debug("TypeError: %s", e)
                # this happens when it tries to instantiate the original
                # abstract class.
                pass
            except Exception as e:
                _wtflog.debug("Exception: %s", e)
                # Unexpected exception.
                raise e

        # If no matching classes.
        if not isinstance(current_matched_page, PageObject):
            raise NoMatchingPageError(
                u("There's, no matching classes to this page. URL:{0}").format(
                    webdriver.current_url))
        else:
            return current_matched_page