<commit_before>********************
Building PageObjects
********************

Overview
========
.. automodule:: holmium.core 

A typical PageObject built with :mod:`holmium.core` has the following composition:

* :class:`Page`
    * :class:`Element` 
    * :class:`Elements` 
    * :class:`ElementMap` 
    * :class:`Section` 
        * :class:`Element` 
        * :class:`Elements` 
        * :class:`ElementMap` 
    * :class:`Sections` 
        * :class:`Element` 
        * :class:`Elements` 
        * :class:`ElementMap` 

A Page is initalized with a :class:`selenium.webdriver.remote.webdriver.WebDriver` 
instance and can take some optional arguments.

.. code-block:: python

    class MyPage(Page):
        pass 

    driver = selenium.webdriver.Firefox()
    p = MyPage(driver)
    p = MyPage(driver, url = "http://www.google.com")
    p = MyPage(driver, url = "http://www.google.com", iframe = "#frame")

Providing the ``url`` argument will result in the driver navigating to the ``url`` 
when the :class:`Page` is initialized. The ``iframe`` argument forces an 
invocation of :meth:`selenium.webdriver.remote.webdriver.WebDriver.switch_to_frame` 
everytime an element in the :class:`Page` is accessed.

The ``webdriver`` that is supplied to a :class:`Page` is used when looking up any 
:class:`Element`, :class:`Elements` or :class:`ElementMap` 
that is declared as a static member. 

To understand the wiring between a :class:`Page` and its elements try out 
the example below in a python repl.

.. code-block:: python

    from holmium.core import Page, Element, Elements, ElementMap, Locators 
    import selenium.webdriver 
    driver = selenium.webdriver.Firefox()
    class GooglePage(Page):
        search_box = Element( Locators.NAME, "q", timeout = 1)
        google_footer = ElementMap ( Locators.CSS_SELECTOR, "#fll>div>a" , timeout = 1 ) 

    g = GooglePage(driver, url="http://www.google.ca")
    g.search_box 
    # <selenium.webdriver.remote.webelement.WebElement object at 0x10b50e450>
    g.google_footer 
    # OrderedDict([(u'Advertising Programs', <selenium.webdriver.remote.webelement.WebElement object at 0x10b35f250>), .....
    g.google_footer["About Google"]
    # <selenium.webdriver.remote.webelement.WebElement object at 0x10b35f450> 
    g.google_footer["About Google"].get_attribute("href")
    # u'http://www.google.ca/intl/en/about.html
    driver.get("http://www.google.co.tz")
    g.google_footer["Kila Kitu Kuhusu Google"].get_attribute("href")
    # u'https://www.google.co.tz/intl/sw/about.html'


Both the element ``search_box`` and the collection of footer links ``google_footer`` are looked up using the driver that was 
passed into the ``GooglePage`` instance.

Sections
========
:class:`Section` objects can be used to further encapsulate 
blocks of page logic that may either be reusable between different pages or
accessed from within different parts of the page in a similar manner. Examples of 
such usecases are menus, footers and collections that may not follow a standard list or map formation. 

Take for example a page with the following structure.

.. code-block:: python

    from holmium.core import Page, Section, Element, Elements, ElementMap, Locators 
    import selenium.webdriver 
    
    headlines_snippet = """
    <html>
        <body><commit_msg>update example to be in sync with google<commit_after>********************
Building PageObjects
********************

Overview
========
.. automodule:: holmium.core 

A typical PageObject built with :mod:`holmium.core` has the following composition:

* :class:`Page`
    * :class:`Element` 
    * :class:`Elements` 
    * :class:`ElementMap` 
    * :class:`Section` 
        * :class:`Element` 
        * :class:`Elements` 
        * :class:`ElementMap` 
    * :class:`Sections` 
        * :class:`Element` 
        * :class:`Elements` 
        * :class:`ElementMap` 

A Page is initalized with a :class:`selenium.webdriver.remote.webdriver.WebDriver` 
instance and can take some optional arguments.

.. code-block:: python

    class MyPage(Page):
        pass 

    driver = selenium.webdriver.Firefox()
    p = MyPage(driver)
    p = MyPage(driver, url = "http://www.google.com")
    p = MyPage(driver, url = "http://www.google.com", iframe = "#frame")

Providing the ``url`` argument will result in the driver navigating to the ``url`` 
when the :class:`Page` is initialized. The ``iframe`` argument forces an 
invocation of :meth:`selenium.webdriver.remote.webdriver.WebDriver.switch_to_frame` 
everytime an element in the :class:`Page` is accessed.

The ``webdriver`` that is supplied to a :class:`Page` is used when looking up any 
:class:`Element`, :class:`Elements` or :class:`ElementMap` 
that is declared as a static member. 

To understand the wiring between a :class:`Page` and its elements try out 
the example below in a python repl.

.. code-block:: python

    from holmium.core import Page, Element, Elements, ElementMap, Locators 
    import selenium.webdriver 
    driver = selenium.webdriver.Firefox()
    class GooglePage(Page):
        search_box = Element( Locators.NAME, "q", timeout = 1)
        google_footer = ElementMap ( Locators.CSS_SELECTOR, "#fsl>a" , timeout = 1 )

    g = GooglePage(driver, url="http://www.google.ca")
    g.search_box 
    # <selenium.webdriver.remote.webelement.WebElement object at 0x10b50e450>
    g.google_footer 
    # OrderedDict([(u'Advertising', <selenium.webdriver.remote.webelement.WebElement object at 0x10b35f250>), .....
    g.google_footer["About"]
    # <selenium.webdriver.remote.webelement.WebElement object at 0x10b35f450> 
    g.google_footer["About"].get_attribute("href")
    # u'http://www.google.ca/intl/en/about.html?fg=1'
    driver.get("http://www.google.co.tz")
    g.google_footer["Kuhusu Google"].get_attribute("href")
    # u'https://www.google.co.tz/intl/sw/about.html?fg=1'


Both the element ``search_box`` and the collection of footer links ``google_footer`` are looked up using the driver that was 
passed into the ``GooglePage`` instance.

Sections
========
:class:`Section` objects can be used to further encapsulate 
blocks of page logic that may either be reusable between different pages or
accessed from within different parts of the page in a similar manner. Examples of 
such usecases are menus, footers and collections that may not follow a standard list or map formation. 

Take for example a page with the following structure.

.. code-block:: python

    from holmium.core import Page, Section, Element, Elements, ElementMap, Locators 
    import selenium.webdriver 
    
    headlines_snippet = """
    <html>
        <body>
{'fraction_non_alphanumeric': 0.1301864101022249, 'fraction_numerical': 0.008117859290438966, 'mean_word_length': 3.7589413447782545, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 16, 'https://': 2, 'lorem ipsum': 0, 'www.': 12, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5407380', 'n_tokens_mistral': 2107, 'n_tokens_neox': 1952, 'n_words': 599}