Exemplo n.º 1
0
def test_detour_is_non_reentrant(web_fixture):
    """Once detoured to a View marked as the start of a Detour, a Bookmark to that View itself
    will not re-enter the detour.
    """
    class MainUI(UserInterface):
        def assemble(self):
            self.define_page(HTML5Page).use_layout(BasicPageLayout())

            step1 = self.define_view('/firstStepOfDetour',
                                     title='Step 1',
                                     detour=True)
            step1.set_slot('main',
                           A.factory_from_bookmark(step1.as_bookmark(self)))

            home = self.define_view('/initial', title='View a')
            home.set_slot('main',
                          A.factory_from_bookmark(step1.as_bookmark(self)))

    wsgi_app = web_fixture.new_wsgi_app(site_root=MainUI)
    browser = Browser(wsgi_app)

    def locationIsSetToReturnTo(url_path):
        return urllib.parse.parse_qs(
            browser.current_url.query)['returnTo'] == [url_path]

    browser.open('/initial')
    browser.click(XPath.link().with_text('Step 1'))
    assert browser.current_url.path == '/firstStepOfDetour'
    assert locationIsSetToReturnTo('http://localhost/initial')

    browser.click(XPath.link().with_text('Step 1'))
    assert browser.current_url.path == '/firstStepOfDetour'
    assert locationIsSetToReturnTo('http://localhost/initial')
Exemplo n.º 2
0
def language_menu(fixture):
    """A Nav can also be constructed to let a user choose to view the same page in 
       another of the supported languages."""
    class PanelWithMenu(Div):
        def __init__(self, view):
            super(PanelWithMenu, self).__init__(view)
            self.add_child(Menu(view).with_languages())
            self.add_child(P(view, text=_('This is an English sentence.')))

    wsgi_app = fixture.new_wsgi_app(child_factory=PanelWithMenu.factory())

    browser = Browser(wsgi_app)
    browser.open('/')

    vassert(
        browser.is_element_present(
            XPath.paragraph_containing('This is an English sentence.')))

    browser.click(XPath.link_with_text('Afrikaans'))
    vassert(
        browser.is_element_present(
            XPath.paragraph_containing('Hierdie is \'n sin in Afrikaans.')))

    browser.click(XPath.link_with_text('English (United Kingdom)'))
    vassert(
        browser.is_element_present(
            XPath.paragraph_containing('This is an English sentence.')))
Exemplo n.º 3
0
    def posting_to_view(self, fixture):
        """ONLY If a View is writable, may it be POSTed to"""
        def disallowed():
            return False

        class MyForm(Form):
            def __init__(self, view):
                super(MyForm, self).__init__(view, 'myform')
                self.define_event_handler(self.events.an_event)
                self.add_child(ButtonInput(self, self.events.an_event))

            @exposed
            def events(self, events):
                events.an_event = Event(label='Click me')

        class MainUI(UserInterface):
            def assemble(self):
                self.define_page(HTML5Page).use_layout(
                    PageLayout(
                        contents_layout=ColumnLayout('main').with_slots()))
                home = self.define_view('/a_view',
                                        'Title',
                                        write_check=disallowed)
                home.set_slot('main', MyForm.factory())

        wsgi_app = fixture.new_wsgi_app(site_root=MainUI)
        browser = Browser(wsgi_app)

        browser.open('/a_view')
        browser.click(XPath.button_labelled('Click me'), status=403)
Exemplo n.º 4
0
    def transitions_to_parameterised_views_error(self, fixture):
        """If an Event triggers a Transition to a parameterised View, and it was not bound to the arguments
           expected by the target View, an error is raised."""
        class ModelObject(object):
            @exposed
            def events(self, events):
                events.an_event = Event(label='Click me')

        model_object = ModelObject()

        class FormWithIncorrectButtonToParameterisedView(Form):
            def __init__(self, view):
                super(FormWithIncorrectButtonToParameterisedView,
                      self).__init__(view, 'test_events')
                self.add_child(
                    ButtonInput(
                        self,
                        model_object.events.an_event.with_arguments(arg1='1',
                                                                    arg2='2')))

        class ParameterisedView(UrlBoundView):
            def assemble(self, object_key=None):
                self.title = 'View for: %s' % object_key

        class UIWithParameterisedViews(UserInterface):
            def assemble(self):
                slot_definitions = {
                    'main':
                    FormWithIncorrectButtonToParameterisedView.factory()
                }
                normal_view = self.define_view(
                    '/static',
                    title='Static',
                    slot_definitions=slot_definitions)
                parameterised_view = self.define_view(
                    '/dynamic',
                    view_class=ParameterisedView,
                    object_key=Field(required=True))
                self.define_transition(model_object.events.an_event,
                                       normal_view, parameterised_view)

        class MainUI(UserInterface):
            def assemble(self):
                self.define_page(HTML5Page).use_layout(
                    PageLayout(
                        contents_layout=ColumnLayout('main').with_slots()))
                self.define_user_interface('/a_ui',
                                           UIWithParameterisedViews,
                                           IdentityDictionary(),
                                           name='test_ui')

        wsgi_app = fixture.new_wsgi_app(site_root=MainUI)
        browser = Browser(wsgi_app)

        browser.open('/a_ui/static')
        with expected(ProgrammerError):
            browser.click(XPath.button_labelled('Click me'))
Exemplo n.º 5
0
    def detour_to_login(self, fixture):
        browser = Browser(fixture.wsgi_app)

        browser.open('/inbox/')
        vassert(browser.location_path == '/accounts/login')
        browser.type('//input[@name="email"]', fixture.system_account.email)
        browser.type('//input[@name="password"]',
                     fixture.system_account.password)
        browser.click('//input[@value="Log in"]')
        vassert(browser.location_path == '/inbox/')
Exemplo n.º 6
0
    def detours_and_return_transitions(self, fixture):
        """Detour is a special exception that will redirect the browser to another View, but it also does the
           necessary housekeeping that will allow a return_transition to let the browser return to where the 
           Detour was thrown."""

        fixture.make_precondition_pass = False

        class UIWithDetour(UserInterface):
            def assemble(self):
                event = Event(label='Click me')
                event.bind('anevent', None)
                viewa = self.define_view('/viewa', title='View a')
                slot_with_button = {'main': FormWithButton.factory(event)}

                step1 = self.define_view('/firstStepOfDetour',
                                         title='Step 1',
                                         slot_definitions=slot_with_button)
                step2 = self.define_view('/lastStepOfDetour',
                                         title='Step 2',
                                         slot_definitions=slot_with_button)

                viewa.add_precondition(
                    ViewPreCondition(lambda: fixture.make_precondition_pass,
                                     exception=Detour(
                                         step1.as_bookmark(self))))
                self.define_transition(event, step1, step2)
                self.define_return_transition(event, step2)

        class MainUI(UserInterface):
            def assemble(self):
                self.define_page(HTML5Page).use_layout(
                    PageLayout(
                        contents_layout=ColumnLayout('main').with_slots()))
                self.define_user_interface('/a_ui',
                                           UIWithDetour,
                                           IdentityDictionary(),
                                           name='test_ui')

        wsgi_app = fixture.new_wsgi_app(site_root=MainUI)
        browser = Browser(wsgi_app)
        fixture.did_something = False

        fixture.make_precondition_pass = False
        browser.open('/a_ui/viewa')
        vassert(browser.location_path == '/a_ui/firstStepOfDetour')

        browser.click('//input[@type="submit"]')
        vassert(browser.location_path == '/a_ui/lastStepOfDetour')

        fixture.make_precondition_pass = True
        browser.click('//input[@type="submit"]')
        vassert(browser.location_path == '/a_ui/viewa')

        # The query string is cleared after such a return (it is used to remember where to return to)
        vassert(browser.location_query_string == '')
Exemplo n.º 7
0
def test_detour_to_login(web_fixture, party_account_fixture, workflow_web_fixture):
    fixture = workflow_web_fixture

    browser = Browser(fixture.wsgi_app)

    browser.open('/inbox/')
    assert browser.current_url.path == '/accounts/login'
    browser.type('//input[@name="login_form-email"]', party_account_fixture.system_account.email)
    browser.type('//input[@name="login_form-password"]', party_account_fixture.system_account.password)
    browser.click('//input[@value="Log in"]')
    assert browser.current_url.path == '/inbox/'
Exemplo n.º 8
0
def test_addressbook2(web_fixture, addressbook2_scenario):

    browser = Browser(addressbook2_scenario.wsgi_app)
    browser.open('/')

    browser.type(XPath.input_labelled('Name'), 'John')
    browser.type(XPath.input_labelled('Email'), '*****@*****.**')
    browser.click(XPath.button_labelled('Save'))

    assert browser.is_element_present(
        XPath.paragraph().including_text('John: [email protected]'))
Exemplo n.º 9
0
def test_addressbook2(fixture):
    browser = Browser(fixture.wsgi_app)
    browser.open('/')

    browser.type(XPath.input_labelled('Name'), 'John')
    browser.type(XPath.input_labelled('Email'), '*****@*****.**')
    browser.click(XPath.button_labelled('Save'))

    vassert(
        browser.is_element_present(
            XPath.paragraph_containing('John: [email protected]')))
Exemplo n.º 10
0
def test_detour_to_login(web_fixture, party_account_fixture, workflow_web_fixture):
    fixture = workflow_web_fixture

    browser = Browser(fixture.wsgi_app)

    browser.open('/inbox/')
    assert browser.current_url.path == '/accounts/login'
    browser.type(XPath.input_labelled('Email'), party_account_fixture.system_account.email)
    browser.type(XPath.input_labelled('Password'), party_account_fixture.system_account.password)
    browser.click(XPath.button_labelled('Log in'))
    assert browser.current_url.path == '/inbox/'
Exemplo n.º 11
0
def test_take_and_release_task(web_fixture, task_queue_fixture, workflow_web_fixture):
    fixture = workflow_web_fixture

    browser = Browser(fixture.wsgi_app)
    task = task_queue_fixture.task

    take_task_button = XPath.button_labelled('Take')
    defer_task_button = XPath.button_labelled('Defer')
    release_task_button = XPath.button_labelled('Release')
    go_to_task_button = XPath.button_labelled('Go to')

    web_fixture.log_in(browser=browser)
    browser.open('/inbox/')

    browser.click(take_task_button)
    assert browser.current_url.path == '/inbox/task/%s' % task.id

    browser.click(defer_task_button)
    assert browser.current_url.path == '/inbox/'

    browser.click(go_to_task_button)
    assert browser.current_url.path == '/inbox/task/%s' % task.id

    browser.click(release_task_button)
    assert browser.current_url.path == '/inbox/'
Exemplo n.º 12
0
def test_domain_exception(web_fixture, session_scope_fixture):
    """Typing the wrong password results in an error message being shown to the user."""

    browser = Browser(web_fixture.new_wsgi_app(site_root=SessionScopeUI))
    user = session_scope_fixture.user

    browser.open('/')
    browser.click(XPath.link().with_text('Log in'))

    browser.type(XPath.input_labelled('Email'), '*****@*****.**')
    browser.type(XPath.input_labelled('Password'), 'wrong password')
    browser.click(XPath.button_labelled('Log in'))

    assert browser.is_element_present(XPath.div().including_text('The email/password given do not match'))
Exemplo n.º 13
0
def test_take_and_release_task(web_fixture, task_queue_fixture, workflow_web_fixture):
    fixture = workflow_web_fixture

    browser = Browser(fixture.wsgi_app)
    task = task_queue_fixture.task

    take_task_button = '//input[@value="Take"]'
    defer_task_button = '//input[@value="Defer"]'
    release_task_button = '//input[@value="Release"]'
    go_to_task_button = '//input[@value="Go to"]'

    web_fixture.log_in(browser=browser)
    browser.open('/inbox/')

    browser.click(take_task_button)
    assert browser.current_url.path == '/inbox/task/%s' % task.id

    browser.click(defer_task_button)
    assert browser.current_url.path == '/inbox/'

    browser.click(go_to_task_button)
    assert browser.current_url.path == '/inbox/task/%s' % task.id

    browser.click(release_task_button)
    assert browser.current_url.path == '/inbox/'
Exemplo n.º 14
0
    def guards(self, fixture):
        """Guards can be set on Transitions. A Transition is only elegible for firing if its guard is True."""
        fixture.guard_value = None
        adjustable_guard = Action(lambda: fixture.guard_value)

        false_guard = Action(lambda: False)

        class UIWithGuardedTransitions(UserInterface):
            def assemble(self):
                event = Event(label='Click me')
                event.bind('anevent', None)
                slot_definitions = {'main': FormWithButton.factory(event)}
                viewa = self.define_view('/viewa',
                                         title='View a',
                                         slot_definitions=slot_definitions)
                viewb = self.define_view('/viewb', title='View b')
                viewc = self.define_view('/viewc', title='View c')
                self.define_transition(event, viewa, viewb, guard=false_guard)
                self.define_transition(event,
                                       viewa,
                                       viewc,
                                       guard=adjustable_guard)

        class MainUI(UserInterface):
            def assemble(self):
                self.define_page(HTML5Page).use_layout(
                    PageLayout(
                        contents_layout=ColumnLayout('main').with_slots()))
                self.define_user_interface('/a_ui',
                                           UIWithGuardedTransitions,
                                           IdentityDictionary(),
                                           name='test_ui')

        wsgi_app = fixture.new_wsgi_app(site_root=MainUI)
        browser = Browser(wsgi_app)

        # The transition with True guard is the one followed
        fixture.guard_value = True
        browser.open('/a_ui/viewa')
        browser.click('//input[@value="Click me"]')
        vassert(browser.location_path == '/a_ui/viewc')

        # If there is no Transition with a True guard, fail
        fixture.guard_value = False
        browser.open('/a_ui/viewa')
        with expected(ProgrammerError):
            browser.click('//input[@value="Click me"]')
Exemplo n.º 15
0
def test_pageflow1(web_fixture, pageflow1_scenario):

    browser = Browser(pageflow1_scenario.wsgi_app)
    browser.open('/')

    assert browser.is_element_present('//ul[contains(@class,"nav")]')

    browser.click(XPath.link().with_text('Add'))
    assert browser.current_url.path == '/add'

    browser.type(XPath.input_labelled('Name'), 'John')
    browser.type(XPath.input_labelled('Email'), '*****@*****.**')
    browser.click(XPath.button_labelled('Save'))

    assert browser.current_url.path == '/'
    assert browser.is_element_present(
        XPath.paragraph().including_text('John: [email protected]'))
Exemplo n.º 16
0
def test_pageflow2(fixture):
    browser = Browser(fixture.wsgi_app)
    browser.open('/')

    vassert(browser.is_element_present('//ul[contains(@class,"nav")]'))

    browser.click(XPath.link_with_text('Add an address'))
    vassert(browser.location_path == '/add')

    browser.type(XPath.input_labelled('Name'), 'John')
    browser.type(XPath.input_labelled('Email'), '*****@*****.**')
    browser.click(XPath.button_labelled('Save'))

    vassert(browser.location_path == '/')
    vassert(
        browser.is_element_present(
            XPath.paragraph_containing('John: [email protected]')))
Exemplo n.º 17
0
    def basic_transition(self, fixture):
        """Transitions express how the browser is ferried between Views in reaction to user-initiated Events."""
        def do_something():
            fixture.did_something = True

        class UIWithTwoViews(UserInterface):
            def assemble(self):
                event = Event(label='Click me', action=Action(do_something))
                event.bind('anevent', None)
                slot_definitions = {'main': FormWithButton.factory(event)}
                viewa = self.define_view('/viewa',
                                         title='View a',
                                         slot_definitions=slot_definitions)
                viewb = self.define_view('/viewb',
                                         title='View b',
                                         slot_definitions=slot_definitions)
                self.define_transition(event, viewa, viewb)

        class MainUI(UserInterface):
            def assemble(self):
                self.define_page(HTML5Page).use_layout(
                    PageLayout(
                        contents_layout=ColumnLayout('main').with_slots()))
                self.define_user_interface('/a_ui',
                                           UIWithTwoViews,
                                           IdentityDictionary(),
                                           name='test_ui')

        wsgi_app = fixture.new_wsgi_app(site_root=MainUI)
        browser = Browser(wsgi_app)

        # The transition works from viewa
        fixture.did_something = False
        browser.open('/a_ui/viewa')
        browser.click('//input[@value="Click me"]')
        vassert(browser.location_path == '/a_ui/viewb')
        vassert(fixture.did_something)

        # The transition does not work from viewb
        fixture.did_something = False
        browser.open('/a_ui/viewb')
        with expected(ProgrammerError):
            browser.click('//input[@value="Click me"]')
        vassert(not fixture.did_something)
Exemplo n.º 18
0
    def detours_and_explicit_return_view(self, fixture):
        """A Detour can also explicitly set the View to return to."""
        class UIWithDetour(UserInterface):
            def assemble(self):
                event = Event(label='Click me')
                event.bind('anevent', None)
                viewa = self.define_view('/viewa', title='View a')
                explicit_return_view = self.define_view(
                    '/explicitReturnView', title='Explicit Return View')

                slot_with_button = {'main': FormWithButton.factory(event)}
                detour = self.define_view('/detour',
                                          title='Detour',
                                          slot_definitions=slot_with_button)

                viewa.add_precondition(
                    ViewPreCondition(
                        lambda: False,
                        exception=Detour(
                            detour.as_bookmark(self),
                            return_to=explicit_return_view.as_bookmark(self))))
                self.define_return_transition(event, detour)

        class MainUI(UserInterface):
            def assemble(self):
                self.define_page(HTML5Page).use_layout(
                    PageLayout(
                        contents_layout=ColumnLayout('main').with_slots()))
                self.define_user_interface('/a_ui',
                                           UIWithDetour,
                                           IdentityDictionary(),
                                           name='test_ui')

        wsgi_app = fixture.new_wsgi_app(site_root=MainUI)
        browser = Browser(wsgi_app)

        browser.open('/a_ui/viewa')
        vassert(browser.location_path == '/a_ui/detour')

        browser.click('//input[@type="submit"]')
        vassert(browser.location_path == '/a_ui/explicitReturnView')

        # The query string is cleared after such a return (it is used to remember where to return to)
        vassert(browser.location_query_string == '')
Exemplo n.º 19
0
    def local_transition(self, fixture):
        """A local Transition has its source as its target."""
        def do_something():
            fixture.did_something = True

        fixture.guard_passes = True
        guard = Action(lambda: fixture.guard_passes)

        class UIWithAView(UserInterface):
            def assemble(self):
                event = Event(label='Click me', action=Action(do_something))
                event.bind('anevent', None)
                slot_definitions = {'main': FormWithButton.factory(event)}
                viewa = self.define_view('/viewa',
                                         title='View a',
                                         slot_definitions=slot_definitions)
                self.define_local_transition(event, viewa, guard=guard)

        class MainUI(UserInterface):
            def assemble(self):
                self.define_page(HTML5Page).use_layout(
                    PageLayout(
                        contents_layout=ColumnLayout('main').with_slots()))
                self.define_user_interface('/a_ui',
                                           UIWithAView,
                                           IdentityDictionary(),
                                           name='test_ui')

        wsgi_app = fixture.new_wsgi_app(site_root=MainUI)
        browser = Browser(wsgi_app)

        # The transition works from viewa
        fixture.did_something = False
        browser.open('/a_ui/viewa')
        browser.click('//input[@value="Click me"]')
        vassert(browser.location_path == '/a_ui/viewa')
        vassert(fixture.did_something)

        # But it is also guarded
        fixture.guard_passes = False
        browser.open('/a_ui/viewa')
        with expected(ProgrammerError):
            browser.click('//input[@value="Click me"]')
Exemplo n.º 20
0
def test_basic_transition(web_fixture):
    """Transitions express how the browser is ferried between Views in reaction to user-initiated Events."""
    fixture = web_fixture

    def do_something():
        fixture.did_something = True

    class UIWithTwoViews(UserInterface):
        def assemble(self):
            event = Event(label='Click me', action=Action(do_something))
            event.bind('anevent', None)
            viewa = self.define_view('/viewa', title='View a')
            viewa.set_slot('main', FormWithButton.factory(event))
            viewb = self.define_view('/viewb', title='View b')
            viewb.set_slot('main', FormWithButton.factory(event))
            self.define_transition(event, viewa, viewb)

    class MainUI(UserInterface):
        def assemble(self):
            self.define_page(HTML5Page).use_layout(BasicPageLayout())
            self.define_user_interface('/a_ui',
                                       UIWithTwoViews,
                                       IdentityDictionary(),
                                       name='test_ui')

    wsgi_app = web_fixture.new_wsgi_app(site_root=MainUI)
    browser = Browser(wsgi_app)

    # The transition works from viewa
    fixture.did_something = False
    browser.open('/a_ui/viewa')
    browser.click('//input[@value="Click me"]')
    assert browser.current_url.path == '/a_ui/viewb'
    assert fixture.did_something

    # The transition does not work from viewb
    fixture.did_something = False
    browser.open('/a_ui/viewb')
    with expected(ProgrammerError):
        browser.click('//input[@value="Click me"]')
    assert not fixture.did_something
Exemplo n.º 21
0
def test_local_transition(web_fixture):
    """A local Transition has its source as its target."""
    fixture = web_fixture

    def do_something():
        fixture.did_something = True

    fixture.guard_passes = True
    guard = Action(lambda: fixture.guard_passes)

    class UIWithAView(UserInterface):
        def assemble(self):
            event = Event(label='Click me', action=Action(do_something))
            event.bind('anevent', None)
            viewa = self.define_view('/viewa', title='View a')
            viewa.set_slot('main', FormWithButton.factory(event))
            self.define_local_transition(event, viewa, guard=guard)

    class MainUI(UserInterface):
        def assemble(self):
            self.define_page(HTML5Page).use_layout(BasicPageLayout())
            self.define_user_interface('/a_ui',
                                       UIWithAView,
                                       IdentityDictionary(),
                                       name='test_ui')

    wsgi_app = web_fixture.new_wsgi_app(site_root=MainUI)
    browser = Browser(wsgi_app)

    # The transition works from viewa
    fixture.did_something = False
    browser.open('/a_ui/viewa')
    browser.click('//input[@value="Click me"]')
    assert browser.current_url.path == '/a_ui/viewa'
    assert fixture.did_something

    # But it is also guarded
    fixture.guard_passes = False
    browser.open('/a_ui/viewa')
    with expected(ProgrammerError):
        browser.click('//input[@value="Click me"]')
Exemplo n.º 22
0
def test_detours_and_explicit_return_view(web_fixture):
    """A Detour can also explicitly set the View to return to."""
    class UIWithDetour(UserInterface):
        def assemble(self):
            event = Event(label='Click me')
            event.bind('anevent', None)
            viewa = self.define_view('/viewa', title='View a')
            explicit_return_view = self.define_view(
                '/explicitReturnView', title='Explicit Return View')

            detour = self.define_view('/detour', title='Detour')
            detour.set_slot('main', FormWithButton.factory(event))

            viewa.add_precondition(
                ViewPreCondition(
                    lambda: False,
                    exception=Detour(
                        detour.as_bookmark(self),
                        return_to=explicit_return_view.as_bookmark(self))))
            self.define_return_transition(event, detour)

    class MainUI(UserInterface):
        def assemble(self):
            self.define_page(HTML5Page).use_layout(BasicPageLayout())
            self.define_user_interface('/a_ui',
                                       UIWithDetour,
                                       IdentityDictionary(),
                                       name='test_ui')

    wsgi_app = web_fixture.new_wsgi_app(site_root=MainUI)
    browser = Browser(wsgi_app)

    browser.open('/a_ui/viewa')
    assert browser.current_url.path == '/a_ui/detour'

    browser.click('//input[@type="submit"]')
    assert browser.current_url.path == '/a_ui/explicitReturnView'

    # The query string is cleared after such a return (it is used to remember where to return to)
    assert browser.current_url.query == ''
Exemplo n.º 23
0
def test_adding_an_address(web_fixture):
    """To add a new address, a user clicks on "Add Address" link on the menu, then supplies the 
       information for the new address and clicks the Save button. Upon successful addition of the
       address, the user is returned to the home page where the new address is now listed."""

    browser = Browser(web_fixture.new_wsgi_app(site_root=AddressBookUI))

    browser.open('/')
    browser.click(XPath.link().with_text('Add'))

    actual_title = browser.title
    assert actual_title == 'Add', 'Expected to be on the Add an address page'

    browser.type(XPath.input_labelled('Name'), 'John Doe')
    browser.type(XPath.input_labelled('Email'), '*****@*****.**')

    browser.click(XPath.button_labelled('Save'))

    actual_title = browser.title
    assert actual_title == 'Show', 'Expected to be back on the home page after editing'

    assert browser.is_element_present(XPath.paragraph().including_text('John Doe: [email protected]')), \
           'Expected the newly added address to be listed on the home page'
Exemplo n.º 24
0
def test_linking_to_views_marked_as_detour(web_fixture):
    """A View can be marked as the start of a Detour. Where used, a Bookmark for such a View
       will automatically include a returnTo in the its query string. This allows an
       eventual return_transition (or similar) to return to where, eg, a link was clicked from.
       This mechanism works for returning across UserInterfaces."""
    class UIWithLink(UserInterface):
        def assemble(self, bookmark=None):
            self.bookmark = bookmark
            self.define_view('/initial', title='View a').set_slot(
                'main', A.factory_from_bookmark(self.bookmark))

    class UIWithDetour(UserInterface):
        def assemble(self):
            event = Event(label='Click me')
            event.bind('anevent', None)

            step1 = self.define_view('/firstStepOfDetour',
                                     title='Step 1',
                                     detour=True)
            step1.set_slot('main', FormWithButton.factory(event))
            step2 = self.define_view('/lastStepOfDetour', title='Step 2')
            step2.set_slot('main', FormWithButton.factory(event))

            self.define_transition(event, step1, step2)
            self.define_return_transition(event, step2)

    class MainUI(UserInterface):
        def assemble(self):
            self.define_page(HTML5Page).use_layout(BasicPageLayout())
            detour_ui = self.define_user_interface('/uiWithDetour',
                                                   UIWithDetour,
                                                   IdentityDictionary(),
                                                   name='second_ui')
            bookmark = detour_ui.get_bookmark(
                relative_path='/firstStepOfDetour')
            self.define_user_interface('/uiWithLink',
                                       UIWithLink,
                                       IdentityDictionary(),
                                       name='first_ui',
                                       bookmark=bookmark)

    wsgi_app = web_fixture.new_wsgi_app(site_root=MainUI)
    browser = Browser(wsgi_app)

    browser.open('/uiWithLink/initial')
    browser.click('//a')
    assert browser.current_url.path == '/uiWithDetour/firstStepOfDetour'

    browser.click('//input[@type="submit"]')
    assert browser.current_url.path == '/uiWithDetour/lastStepOfDetour'

    browser.click('//input[@type="submit"]')
    assert browser.current_url.path == '/uiWithLink/initial'

    # The query string is cleared after such a return (it is used to remember where to return to)
    assert browser.current_url.query == ''
Exemplo n.º 25
0
def test_email_retained(web_fixture, session_scope_fixture):
    """The email address used when last logged in is always pre-populated on the Log in page."""

    browser = Browser(web_fixture.new_wsgi_app(site_root=SessionScopeUI))
    user = session_scope_fixture.user

    browser.open('/')
    browser.click(XPath.link().with_text('Log in'))

    browser.type(XPath.input_labelled('Email'), '*****@*****.**')
    browser.type(XPath.input_labelled('Password'), 'topsecret')
    browser.click(XPath.button_labelled('Log in'))

    # Go away from the page, then back
    browser.click(XPath.link().with_text('Home'))
    browser.click(XPath.link().with_text('Log in'))

    # .. then the email is still pre-populated
    typed_value = browser.get_value(XPath.input_labelled('Email'))
    assert typed_value == '*****@*****.**'
Exemplo n.º 26
0
def test_parameterised1(fixture):
    browser = Browser(fixture.wsgi_app)
    browser.open('/')

    browser.click(XPath.link_with_text('Add an address'))
    browser.type(XPath.input_labelled('Name'), 'John')
    browser.type(XPath.input_labelled('Email'), '*****@*****.**')
    browser.click(XPath.button_labelled('Save'))

    vassert(browser.location_path == '/')
    browser.click(XPath.link_with_text('edit'))

    john = Session.query(parameterised1bootstrap.Address).one()
    vassert(browser.location_path == '/edit/%s' % john.id)
    browser.type(XPath.input_labelled('Name'), 'Johnny')
    browser.type(XPath.input_labelled('Email'), '*****@*****.**')
    browser.click(XPath.button_labelled('Update'))

    vassert(browser.location_path == '/')
    vassert(
        browser.is_element_present(
            XPath.paragraph_containing('Johnny: [email protected]')))
Exemplo n.º 27
0
def test_parameterised1(web_fixture, parameterised1_scenario):

    browser = Browser(parameterised1_scenario.wsgi_app)
    browser.open('/')

    browser.click(XPath.link().with_text('Add'))
    browser.type(XPath.input_labelled('Name'), 'John')
    browser.type(XPath.input_labelled('Email'), '*****@*****.**')
    browser.click(XPath.button_labelled('Save'))

    assert browser.current_url.path == '/'
    browser.click(XPath.link().with_text('edit'))

    john = Session.query(parameterised1.Address).one()
    assert browser.current_url.path == '/edit/%s' % john.id
    browser.type(XPath.input_labelled('Name'), 'Johnny')
    browser.type(XPath.input_labelled('Email'), '*****@*****.**')
    browser.click(XPath.button_labelled('Update'))

    assert browser.current_url.path == '/'
    assert browser.is_element_present(
        XPath.paragraph().including_text('Johnny: [email protected]'))
Exemplo n.º 28
0
    def take_and_release_task(self, fixture):
        browser = Browser(fixture.wsgi_app)
        task = fixture.task

        take_task_button = '//input[@value="Take"]'
        defer_task_button = '//input[@value="Defer"]'
        release_task_button = '//input[@value="Release"]'
        go_to_task_button = '//input[@value="Go to"]'

        fixture.log_in(browser=browser)
        browser.open('/inbox/')

        browser.click(take_task_button)
        vassert(browser.location_path == '/inbox/task/%s' % task.id)

        browser.click(defer_task_button)
        vassert(browser.location_path == '/inbox/')

        browser.click(go_to_task_button)
        vassert(browser.location_path == '/inbox/task/%s' % task.id)

        browser.click(release_task_button)
        vassert(browser.location_path == '/inbox/')
Exemplo n.º 29
0
def test_logging_in(web_fixture, session_scope_fixture):
    """A user can log in by going to the Log in page.
       The name of the currently logged in user is displayed on the home page."""

    browser = Browser(web_fixture.new_wsgi_app(site_root=SessionScopeUI))
    user = session_scope_fixture.user

    browser.open('/')
    browser.click(XPath.link().with_text('Log in'))

    browser.type(XPath.input_labelled('Email'), '*****@*****.**')
    browser.type(XPath.input_labelled('Password'), 'topsecret')
    browser.click(XPath.button_labelled('Log in'))

    browser.click(XPath.link().with_text('Home'))
    assert browser.is_element_present(XPath.paragraph().including_text('Welcome John Doe'))
Exemplo n.º 30
0
def test_form_input_validation(web_fixture):
    """Validation of input happens in JS on the client, but also on the server if JS is bypassed."""

    error_xpath = '//form[contains(@class, "reahl-form")]/label[contains(@class, "error")]'

    fixture = web_fixture

    class ModelObject(object):
        def handle_event(self):
            pass

        @exposed
        def events(self, events):
            events.an_event = Event(label='click me',
                                    action=Action(self.handle_event))

        @exposed
        def fields(self, fields):
            fields.field_name = EmailField()

    model_object = ModelObject()

    class MyForm(Form):
        def __init__(self, view, name, other_view):
            super(MyForm, self).__init__(view, name)
            if self.exception:
                self.add_child(
                    P(view, ','.join(self.exception.detail_messages)))
            self.define_event_handler(model_object.events.an_event,
                                      target=other_view)
            self.add_child(ButtonInput(self, model_object.events.an_event))
            text_input = self.add_child(
                TextInput(self, model_object.fields.field_name))
            if text_input.validation_error:
                self.add_child(self.create_error_label(text_input))

    class MainUI(UserInterface):
        def assemble(self):
            self.define_page(HTML5Page).use_layout(BasicPageLayout())
            home = self.define_view('/', title='Home page')
            other_view = self.define_view('/page2', title='Page 2')
            home.set_slot('main', MyForm.factory('myform', other_view))

    wsgi_app = fixture.new_wsgi_app(site_root=MainUI, enable_js=True)

    # Case: form validation fails in JS on the client
    #  - Form submission is blocked
    #  - Error message is displayed
    fixture.reahl_server.set_app(wsgi_app)
    fixture.driver_browser.open('/')
    fixture.driver_browser.wait_for_element_not_visible(error_xpath)
    fixture.driver_browser.type('//input[@type="text"]',
                                'not@notvalid',
                                trigger_blur=False,
                                wait_for_ajax=False)
    fixture.driver_browser.press_tab()
    fixture.driver_browser.wait_for_element_visible(error_xpath)

    with fixture.driver_browser.no_page_load_expected():
        fixture.driver_browser.click("//input[@value='click me']")

    error_text = fixture.driver_browser.get_text(error_xpath)
    assert error_text == 'field_name should be a valid email address'

    # .. but the error is removed again upon valid input
    fixture.driver_browser.type('//input[@type="text"]', '*****@*****.**')
    fixture.driver_browser.wait_for_element_not_visible(error_xpath)

    # Case: form validation fails on the server (assuming no JS on the client to block submission)
    #  - ValidationException is raised (which is dealt with as any DomainException)
    browser = Browser(wsgi_app)
    browser.open('/')
    browser.type('//input[@type="text"]', 'not@notvalid')

    browser.click('//input[@type="submit"]')
    assert not hasattr(model_object, 'field_name')
    label = browser.get_html_for('//label')
    input_id = browser.get_id_of('//input[@type="text"]')
    assert label == '<label for="%s" class="error">field_name should be a valid email address</label>' % input_id

    assert Session.query(UserInput).filter_by(key='myform-field_name').count(
    ) == 1  # The invalid input was persisted
    exception = Session.query(PersistedException).one().exception
    assert isinstance(exception, ValidationException)  # Is was persisted
    assert not exception.commit

    # Case: form validation passes (no-js)
    #  - no ValidationException
    #  - all input is translated to python and set as values on the model objects
    #  - any saved input on the form is cleared
    browser.type('//input[@type="text"]', '*****@*****.**')
    browser.click("//input[@value='click me']")
    assert model_object.field_name == '*****@*****.**'

    assert Session.query(UserInput).filter_by(
        key='myform-field_name').count() == 0  # The invalid input was removed
    assert Session.query(
        PersistedException).count() == 0  # The exception was removed

    assert browser.current_url.path == '/page2'

    # Case: form validation passes (js)
    #  - no ValidationException
    #  - all input is translated to python and set as values on the model objects
    fixture.driver_browser.open('/')
    fixture.driver_browser.type('//input[@type="text"]', '*****@*****.**')
    fixture.driver_browser.wait_for_element_not_visible(error_xpath)
    fixture.driver_browser.click("//input[@value='click me']")
    assert model_object.field_name == '*****@*****.**'

    assert fixture.driver_browser.current_url.path == '/page2'