======================
Silva Functional Tests
======================

Introduction
------------
This document highlights the features of the SilvaBrowser API, which is built on
top of the zope testbrowser package. The document will also instruct users how to
run, and build a functional test for Silva.

For developers contributing to the Silva trunk we ask that before checking in 
any new code please run all of the Silva tests, or the testbot will get you!

You have been warned.

To be able to identify functional tests from other Silva tests please use the
following naming conventions:

test_functest_test_name.py

Running a test
--------------
The easiest way to run tests is to use ./bin/zopectl test -m DOT_PATH_TO_TEST.
The m option imports the test as a module, there for the dot path.

To run a specific Silva test, run:
./bin/zopectl -m Products.Silva.tests.test_name

To run all of the Silva tests run:
./bin/zopectl -m Products.Silva.tests

For more information about zope.testbrowser visit:
http://pypi.python.org/pypi/zope.testbrowser/3.4.2

Or you can run ./bin/zopectl test --help.

SilvaBrowser
------------
The SilvaBrowser API allows for navigating, accessing, and acquiring Silva 
specific elements, such as forms, content_types, buttons etc. The methods mimic
actions used in the SMI, such as click an href, click a button, or make content.
'get_' methods allow tester to immediately retrieve the results of actions to 
make assertions.

Basic recipe for a functional test
----------------------------------
A simple functional test would look like this:

import unittest
from SilvaTestCase import SilvaFunctionalTestCase
from SilvaBrowser import SilvaBrowser

class MyFunctionalTest(SilvaFunctionalTestCase):
    """
    this is a test example
    login
    test login success
    make silva document
    test existence of the document
    select and delet the document
    test deletion
    logout
    test logout
    """
    
    def test_example(self):
        # get the SilvaBrowser
        sb = SilvaBrowser()
        # login as manager
        status, url = sb.login('manager', 'secret', sb.smi_url())
        # test login success
        self.assertEquals(status, 200)
        # make silva document
        sb.make_content('Silva Document', id='test_document',
                                          title='Test document')
        # test existence of document
        data = sb.get_content_data()
        self.assertEquals(data[1]['name'], u'Test document')
        # select and delete content
        sb.select_delete_content('test_document')
        # test deletion
        self.failUnless('test_document' in sb.browser.contents)
        # logout
        status, url = sb.click_href_labeled('logout')
        # test logout status
        self.assertEquals(status, 401)

def test_suite():
    suite = unittest.TestSuite()
    suite.addTest(unittest.makeSuite(MyFunctionalTest))
    return suite

SilvaBrowser methods list
------------

click_button_labeled()
    Click on a button or psuedo button (an href dressed up as button).
    Example: 'delete', 'close', 'publish now', 'addables' (psuedo button) 

click_href_labeled()
    Click on an link.
    Example: 'logout', 'index', created or existing content types

click_tab_named()
    Click on a specific tab name.
    Example: 'contents', 'preview', 'access'

get_addables_list()
    Return a list of addable metatypes from the select menu.
    Usage: check what content is available for a particular role.

get_addform_title()
    Return a normalized <h2> title for add forms.
    Example: create Silva Document
    Usage: check if the proper add form, or title is being retrieved.

get_alert_feedback()
    Return the alert message in the page
    Example: Could not delete <<index>>.
    Usage: check if an SMI error occurred.

get_content_data()
    Return a list of dictionaries describing the content objects
    
get_content_ids()
    Return a list of ids for objects in a current container
    Usage: check if existing or created content exists

get_href_named()
    Return an href with a specific label
    Usage: retrieve a link from a specific page to test location

get_listing_h2
    Return the content type and name of the <h2> in the listing table
    Example: Silva Root <<root_name>>

get_status_and_url():
    Return HTTP status and the url
    Usage: check the HTTP error code for logging out or check location

get_status_feedback()
    Return the status message in the page.
    Example: 'Added Silva Folder', 'Version Approved'

get_tabs_named()
    Return a specific tab name from <div class="tabs">
    Example: 'editor'
    Usage: check location specific tabs

get_middleground_buttons()
    Return a specific button from the <div class="middleground">
    Example: 'settings...', 'addables...'
    Usage: check locations specific buttons

get_url()
    Return the current url
    Usage: check location

get_root_url()
    Return the zmi root url
    Usage: jump from current location to the zmi

go()
    Open a specific browser page and return the Http status code and url
    
html2text()
    Return children of an html element, stripping out child elements,
    and normalizing text nodes. Supports click_button_labeled(), 
    get_addform_title(), get_listing_h2(), get_tabs_named(), 
    get_middlegroung_buttons()

login()
    Login to the SMI

logout()
    Logout of the SMI

make_content()
    Makes content of a specific type as a specific user, with one or more fields
    filled in.

make_default_content()

open_file()
    Format the path to data/ for test files.

select_addable()
    Select a meta_type form the addables list.

select_all_content()
    Toggle all content item checkboxes.
    Usage: Selecting all content to close, then delete.

select_content()
    Toggle a content item checkbox.
    Usage: Select a content item to close.

select_delete_content()
    Select and then delete a content item

smi_url()
    Return the smi url of current url.

sef_fields()
    Fill multiple field_object controls where keyword is a fieldname and value.
    This is support for the make_content() method.

set_id_field()
    Set the id field.

set_title_field()
    Set the title field.

set_policy_field()
    Set the policy field.
    Example: Set the default document as 'Silva Document' when creating a Silva
    Folder.

set_image_field()
    Set the image field.

set_file_field()
    Set the file field.

set_ghost_url_field()
    Set the ghost url field.

set_url_field()
    Set the url field.

set_link_type_field()
    Set the link type button.

set_depth_field()
    Set the depth field.
