コード例 #1
0
ファイル: test_files.py プロジェクト: dli7428/reahl
def test_async_upload_domain_exception(web_fixture, toggle_validation_fixture):
    """When a DomainException happens upon uploading via JavaScript, 
       the form is replaced with a rerendered version from the server."""

    fixture = toggle_validation_fixture

    web_fixture.reahl_server.set_app(fixture.new_wsgi_app(enable_js=True))
    browser = web_fixture.driver_browser
    browser.open('/')

    fixture.make_validation_fail = False
    browser.type(XPath.input_labelled('Choose file(s)'), fixture.file_to_upload1.name)

    fixture.make_validation_fail = True
    fixture.mark_nested_form()
    with browser.no_page_load_expected():
        browser.type(XPath.input_labelled('Choose file(s)'), fixture.file_to_upload2.name, trigger_blur=False)
    assert fixture.nested_form_was_reloaded()

    # JS Stuff on re-rendered form still work

    # 1: Server-rendered validation message has been cleared
    assert browser.is_visible(XPath.span().including_text('test validation message')) 
    fixture.make_validation_fail = False
    with browser.no_page_load_expected():
        browser.type(XPath.input_labelled('Choose file(s)'), fixture.file_to_upload2.name)
    browser.wait_for_not(browser.is_visible, XPath.span().including_text('test validation message'))

    # 2: The remove button still happens via ajax
    with browser.no_page_load_expected():
        browser.click(XPath.button_labelled('Remove', filename=fixture.file_to_upload1_name))
        browser.click(XPath.button_labelled('Remove', filename=fixture.file_to_upload2_name))
コード例 #2
0
def pageflow(fixture):
    fixture.start_example_app()
    fixture.driver_browser.open('/')
    fixture.driver_browser.type(XPath.input_labelled('Email address'),
                                '*****@*****.**')
    fixture.driver_browser.type(XPath.input_labelled('Comment'), '')
    with SystemOutStub() as output:
        fixture.driver_browser.click(XPath.button_labelled('Submit'))

        vassert(output.captured_output ==
                '[email protected] submitted a comment:\nNone\n')
        vassert(fixture.driver_browser.current_url.path == '/none')
        output.capture_console_screenshot(
            fixture.new_screenshot_path('pageflow1.txt'))

        fixture.driver_browser.open('/')
        fixture.driver_browser.type(XPath.input_labelled('Email address'),
                                    '*****@*****.**')
        fixture.driver_browser.type(XPath.input_labelled('Comment'),
                                    'some comment text')
        with SystemOutStub() as output:
            fixture.driver_browser.click(XPath.button_labelled('Submit'))

        vassert(output.captured_output ==
                '[email protected] submitted a comment:\nsome comment text\n')
        vassert(fixture.driver_browser.current_url.path == '/thanks')
        output.capture_console_screenshot(
            fixture.new_screenshot_path('pageflow2.txt'))
コード例 #3
0
def test_clear_form_inputs_on_optimistic_concurrency(web_fixture,
                                                     sql_alchemy_fixture,
                                                     concurrency_fixture,
                                                     scenario):
    """A concurrency error is detected upon submit after an exception.
       When a user resets inputs upon such a concurrency error, previous form exceptions and input data are cleared.
    """
    fixture = concurrency_fixture

    with sql_alchemy_fixture.persistent_test_classes(fixture.ModelObject):
        Session.add(fixture.model_object)

        wsgi_app = web_fixture.new_wsgi_app(
            child_factory=fixture.MyForm.factory())
        web_fixture.reahl_server.set_app(wsgi_app)
        browser = web_fixture.driver_browser
        browser.open('/')

        # Concurrency error is detected on submit after an exception
        scenario.cause_exception_on_submit(browser)
        assert fixture.is_any_error_displayed()
        assert not fixture.is_concurrency_error_displayed()

        fixture.make_concurrent_change_in_backend()

        browser.type(XPath.input_labelled('Some field'), 'valid input')
        browser.click(XPath.button_labelled('Submit'))
        assert fixture.is_concurrency_error_displayed()

        # Previous error and inputs are cleared
        browser.click(XPath.button_labelled('Reset input'))

        assert browser.get_value(
            XPath.input_labelled('Some field')) == 'changed by someone else'
        assert not fixture.is_any_error_displayed()
コード例 #4
0
ファイル: test_popup.py プロジェクト: smohaorg/reahl
def test_customising_dialog_buttons(web_fixture, popup_a_fixture):
    """The buttons of the dialog can be customised."""
    class PopupTestPanel(Div):
        def __init__(self, view):
            super().__init__(view)
            popup_a = self.add_child(
                PopupA(view, view.as_bookmark(), '#contents'))
            popup_a.add_js_button('Butt1')
            popup_a.add_js_button('Butt2')
            popup_contents = self.add_child(
                P(view, text='this is the content of the popup'))
            popup_contents.set_id('contents')

    wsgi_app = web_fixture.new_wsgi_app(enable_js=True,
                                        child_factory=PopupTestPanel.factory())
    web_fixture.reahl_server.set_app(wsgi_app)
    browser = web_fixture.driver_browser

    button1_xpath = XPath.button_labelled('Butt1')
    button2_xpath = XPath.button_labelled('Butt2')

    browser.open('/')

    browser.click(XPath.link().with_text('Home page'))
    browser.wait_for(popup_a_fixture.is_popped_up)

    assert browser.is_element_present(button1_xpath)
    assert browser.is_element_present(button2_xpath)
コード例 #5
0
def test_input_validation_cues_javascript_interaction(web_fixture, sql_alchemy_fixture, javascript_validation_scenario):
    """The visual cues rendered server-side can subsequently be manipulated via javascript."""
    fixture = javascript_validation_scenario

    web_fixture.reahl_server.set_app(web_fixture.new_wsgi_app(child_factory=fixture.Form.factory(), enable_js=False))

    browser = fixture.browser

    with sql_alchemy_fixture.persistent_test_classes(fixture.ModelObject):
        fixture.domain_object = fixture.ModelObject()
        Session.add(fixture.domain_object)
        browser.open('/')
        browser.type(XPath.input_labelled('Some input'), '')
        browser.click(XPath.button_labelled('Submit'))

        assert ['is-invalid'] == fixture.get_form_group_highlight_marks(browser, index=0)
        [error] = fixture.get_form_group_errors(browser, index=0)
        assert error.text == 'Some input is required'

        web_fixture.reahl_server.set_app(web_fixture.new_wsgi_app(child_factory=fixture.Form.factory(), enable_js=True))
        browser.open('/')

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

        assert ['is-invalid'] == fixture.get_form_group_highlight_marks(browser, index=0)
        [error] = fixture.get_form_group_errors(browser, index=0)
        assert error.text == 'Some input is required'

        browser.type(XPath.input_labelled('Some input'), 'valid value', trigger_blur=False, wait_for_ajax=False)
        browser.press_tab()

        def form_group_is_marked_success(index):
            return ['is-valid'] == fixture.get_form_group_highlight_marks(browser, index=index)
        assert web_fixture.driver_browser.wait_for(form_group_is_marked_success, 0)
        assert not fixture.get_form_group_errors(browser, index=0)
コード例 #6
0
ファイル: test_files.py プロジェクト: xmonader/reahl
def test_file_upload_input_list_files(web_fixture, file_upload_input_fixture):
    """The FileUploadInput displays a list of files that were uploaded so far."""

    fixture = file_upload_input_fixture

    web_fixture.reahl_server.set_app(fixture.wsgi_app)

    browser = web_fixture.driver_browser
    browser.open('/')

    # Upload one file
    browser.type(XPath.input_labelled('Choose file(s)'),
                 fixture.file_to_upload1.name)
    browser.click(XPath.button_labelled('Upload'))

    assert fixture.uploaded_file_is_listed(fixture.file_to_upload1.name)
    assert not fixture.uploaded_file_is_listed(fixture.file_to_upload2.name)

    # Upload a second file
    browser.type(XPath.input_labelled('Choose file(s)'),
                 fixture.file_to_upload2.name)
    browser.click(XPath.button_labelled('Upload'))

    assert fixture.uploaded_file_is_listed(fixture.file_to_upload1.name)
    assert fixture.uploaded_file_is_listed(fixture.file_to_upload2.name)
コード例 #7
0
def file_upload_input_remove_files(fixture):
    """A user can remove files that were uploaded before the Form which contains the 
       FileUploadInput is submitted."""
    fixture.reahl_server.set_app(fixture.wsgi_app)

    browser = fixture.driver_browser
    browser.open('/')

    # Upload two files
    browser.type(XPath.input_labelled('Choose file(s)'),
                 fixture.file_to_upload1.name)
    browser.click(XPath.button_labelled('Upload'))
    browser.type(XPath.input_labelled('Choose file(s)'),
                 fixture.file_to_upload2.name)
    browser.click(XPath.button_labelled('Upload'))

    # Remove file1
    browser.click(
        XPath.button_labelled('Remove', filename=fixture.file_to_upload1_name))

    vassert(not fixture.uploaded_file_is_listed(fixture.file_to_upload1.name))
    vassert(fixture.uploaded_file_is_listed(fixture.file_to_upload2.name))

    # Only the one file is submitted
    browser.click(XPath.button_labelled('Submit'))
    vassert(
        list(fixture.domain_object.submitted_file_info.keys()) ==
        [fixture.file_to_upload2_name])
コード例 #8
0
ファイル: test_files.py プロジェクト: dli7428/reahl
def test_async_remove(web_fixture, file_upload_input_fixture):
    """With javascript enabled, removing of uploaded files take place via ajax."""

    fixture = file_upload_input_fixture

    web_fixture.reahl_server.set_app(fixture.new_wsgi_app(enable_js=True))
    browser = web_fixture.driver_browser
    browser.open('/')

    # Upload two files
    browser.type(XPath.input_labelled('Choose file(s)'), fixture.file_to_upload1.name)
    browser.click(XPath.button_labelled('Upload'))
    browser.type(XPath.input_labelled('Choose file(s)'), fixture.file_to_upload2.name)
    browser.click(XPath.button_labelled('Upload'))

    # Remove file1
    with browser.no_page_load_expected():
        browser.click(XPath.button_labelled('Remove', filename=fixture.file_to_upload1_name))

    assert not fixture.uploaded_file_is_listed( fixture.file_to_upload1.name ) 
    assert fixture.uploaded_file_is_listed( fixture.file_to_upload2.name ) 

    # The javascript works on DOM elements that have been generated server-side as well:
    browser.refresh()
    with browser.no_page_load_expected():
        browser.click(XPath.button_labelled('Remove', filename=fixture.file_to_upload2_name))

    assert not fixture.uploaded_file_is_listed( fixture.file_to_upload1.name ) 
    assert not fixture.uploaded_file_is_listed( fixture.file_to_upload2.name ) 

    # No files are submitted eventually
    browser.click( XPath.button_labelled('Submit') )
    assert list(fixture.domain_object.submitted_file_info.keys()) == [] 
コード例 #9
0
ファイル: test_files.py プロジェクト: xmonader/reahl
def test_file_upload_input_list_files_clearing(web_fixture,
                                               file_upload_input_fixture,
                                               exception_scenario):
    """The list of uploaded files displayed by the FileUploadInput is cleared 
       once the Form is successfully submitted."""

    fixture = file_upload_input_fixture

    web_fixture.reahl_server.set_app(fixture.wsgi_app)

    browser = web_fixture.driver_browser
    browser.open('/')

    # Upload one file
    browser.type(XPath.input_labelled('Choose file(s)'),
                 fixture.file_to_upload1.name)
    browser.click(XPath.button_labelled('Upload'))

    assert fixture.uploaded_file_is_listed(fixture.file_to_upload1.name)

    # Submit the form:
    browser.click(XPath.button_labelled('Submit'))
    if fixture.domain_object.throws_exception:
        assert fixture.uploaded_file_is_listed(fixture.file_to_upload1.name)
    else:
        assert not fixture.uploaded_file_is_listed(
            fixture.file_to_upload1.name)
コード例 #10
0
ファイル: test_workflow.py プロジェクト: smohaorg/reahl
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/'
コード例 #11
0
def test_inputs_cleared_after_domain_exception_resubmit(web_fixture, disclosed_input_fixture):
    """After a domain exception followed by a successful submit, saved state on the server is 
       cleared, so that newly rendered inputs on the same URL will have defaulted values again."""
    # Also see related comment on test_input_values_retained_upon_domain_exception

    fixture = disclosed_input_fixture

    wsgi_app = web_fixture.new_wsgi_app(enable_js=True, child_factory=fixture.MyForm.factory())
    web_fixture.reahl_server.set_app(wsgi_app)
    browser = web_fixture.driver_browser

    # First get a domain exception
    fixture.raise_domain_exception_on_submit = True
    fixture.default_trigger_field_value = False
    browser.open('/')

    browser.click(XPath.input_labelled('Trigger field'))
    browser.type(XPath.input_labelled('Email'), '*****@*****.**')
    browser.click(XPath.button_labelled('click me'))
    assert browser.is_element_present(XPath.paragraph().including_text('Exception raised'))

    # Then successful commit
    fixture.raise_domain_exception_on_submit = False

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

    # Values are all defaulted like on a first render
    assert not browser.is_element_present(XPath.paragraph().including_text('Exception raised'))
    assert not browser.is_selected(XPath.input_labelled('Trigger field'))
    assert not browser.is_element_present(XPath.paragraph().including_text('Email'))
    browser.click(XPath.input_labelled('Trigger field'))
    assert browser.get_value(XPath.input_labelled('Email')) == ''
コード例 #12
0
ファイル: test_accessbootstrap.py プロジェクト: dli7428/reahl
def test_edit_other(web_fixture, access_domain_fixture, access_ui_fixture):
    """If you may only edit (not add) an address, then you may only edit the email address, not the name."""


    browser = access_ui_fixture.browser
    address_book = access_domain_fixture.address_book
    account = access_domain_fixture.account

    other_address_book = access_domain_fixture.other_address_book
    other_address_book.allow(account, can_edit_addresses=True, can_add_addresses=True)
    Address(address_book=other_address_book, email_address='*****@*****.**', name='Friend').save()

    web_fixture.log_in(browser=browser, system_account=account)
    browser.open('/')

    browser.click(XPath.link().with_text('Address book of [email protected]'))
    browser.click(XPath.button_labelled('Edit'))

    # Case: may edit name
    assert browser.is_element_enabled(XPath.input_labelled('Name'))
    assert browser.is_element_enabled(XPath.input_labelled('Email'))

    # Case: may not edit name
    other_address_book.allow(account, can_edit_addresses=True, can_add_addresses=False  )
    browser.refresh()
    assert not browser.is_element_enabled(XPath.input_labelled('Name'))
    assert browser.is_element_enabled(XPath.input_labelled('Email'))

    browser.type(XPath.input_labelled('Email'), '*****@*****.**')
    browser.click(XPath.button_labelled('Update'))

    assert browser.is_element_present(XPath.paragraph().including_text('Friend: [email protected]'))
コード例 #13
0
ファイル: test_form.py プロジェクト: diopib/reahl
def input_validation_cues(fixture):
    """Visible cues are inserted to indicate the current validation state
       and possible validation error messages to a user. """

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

    vassert(not fixture.get_form_group_highlight_marks(browser, index=0))
    vassert(not fixture.get_form_group_errors(browser, index=0))

    browser.type(XPath.input_labelled('Some input'), '')
    browser.click(XPath.button_labelled('Submit'))

    vassert(['has-danger'] == fixture.get_form_group_highlight_marks(browser,
                                                                     index=0))
    [error] = fixture.get_form_group_errors(browser, index=0)
    vassert(error.text == 'Some input is required')

    browser.type(XPath.input_labelled('Some input'), 'valid value')
    browser.click(XPath.button_labelled('Submit'))

    vassert(['has-success'] == fixture.get_form_group_highlight_marks(browser,
                                                                      index=0))
    vassert(not fixture.get_form_group_errors(browser, index=0))

    browser.type(XPath.input_labelled('Another input'), 'valid value')
    browser.click(XPath.button_labelled('Submit'))

    vassert(not fixture.get_form_group_highlight_marks(browser, index=0))
    vassert(not fixture.get_form_group_errors(browser, index=0))
コード例 #14
0
def test_example(web_fixture, dynamic_example_fixture):
    fixture = dynamic_example_fixture

    wsgi_application = web_fixture.new_wsgi_app(site_root=DynamicUI, enable_js=True)
    web_fixture.reahl_server.set_app(wsgi_application)

    browser = fixture.browser

    browser.open('/')

    # Check calculating totals
    browser.type(fixture.percentage_input_for('Fund A'), '80')
    browser.wait_for(fixture.percentage_total_is, '80')

    browser.type(fixture.percentage_input_for('Fund B'), '80')
    browser.wait_for(fixture.percentage_total_is, '160')

    # Check DomainException upon submit with incorrect totals
    browser.click(XPath.button_labelled('Submit'))    
    browser.wait_for_element_visible(fixture.domain_exception_alert)  

    browser.type(fixture.percentage_input_for('Fund B'), '20')
    browser.wait_for(fixture.percentage_total_is, '100')

    # Check successful submit
    browser.click(XPath.button_labelled('Submit'))
    browser.wait_for_element_not_visible(fixture.domain_exception_alert)  
コード例 #15
0
ファイル: test_files.py プロジェクト: xmonader/reahl
def test_file_upload_input_remove_files(web_fixture,
                                        file_upload_input_fixture):
    """A user can remove files that were uploaded but not yet submitted."""
    fixture = file_upload_input_fixture

    web_fixture.reahl_server.set_app(fixture.wsgi_app)

    browser = web_fixture.driver_browser
    browser.open('/')

    # Upload two files
    browser.type(XPath.input_labelled('Choose file(s)'),
                 fixture.file_to_upload1.name)
    browser.click(XPath.button_labelled('Upload'))
    browser.type(XPath.input_labelled('Choose file(s)'),
                 fixture.file_to_upload2.name)
    browser.click(XPath.button_labelled('Upload'))

    # Remove file1
    browser.click(
        XPath.button_labelled('Remove', filename=fixture.file_to_upload1_name))

    assert not fixture.uploaded_file_is_listed(fixture.file_to_upload1.name)
    assert fixture.uploaded_file_is_listed(fixture.file_to_upload2.name)

    # Only the one file is submitted
    browser.click(XPath.button_labelled('Submit'))
    assert list(fixture.domain_object.submitted_file_info.keys()) == [
        fixture.file_to_upload2_name
    ]
コード例 #16
0
ファイル: test_form.py プロジェクト: xmonader/reahl
def test_button_layouts(web_fixture):
    """A ButtonLayout can be be used on a Button to customise various visual effects."""

    event = Event(label='click me')
    event.bind('event', web_fixture)
    form = Form(web_fixture.view, 'test')
    form.define_event_handler(event)

    # Case: the defaults
    button = Button(form, event).use_layout(ButtonLayout())

    tester = WidgetTester(button)
    [button] = tester.xpath(XPath.button_labelled('click me'))
    assert button.attrib['class'] == 'btn reahl-primitiveinput'

    # Case: possible effects
    form = Form(web_fixture.view, 'test')
    form.define_event_handler(event)
    button = Button(form, event).use_layout(
        ButtonLayout(style='secondary', size='sm', active=True, wide=True))

    tester = WidgetTester(button)
    [button] = tester.xpath(XPath.button_labelled('click me'))
    assert button.attrib[
        'class'] == 'active btn btn-block btn-secondary btn-sm reahl-primitiveinput'
コード例 #17
0
ファイル: test_form.py プロジェクト: xmonader/reahl
def test_input_validation_cues(sql_alchemy_fixture, validation_scenarios):
    """Visible cues are inserted to indicate the current validation state
       and possible validation error messages to a user. """
    fixture = validation_scenarios

    browser = fixture.browser

    with sql_alchemy_fixture.persistent_test_classes(fixture.ModelObject):
        fixture.domain_object = fixture.ModelObject()
        Session.add(fixture.domain_object)
        browser.open('/')

        assert not fixture.get_form_group_highlight_marks(browser, index=0)
        assert not fixture.get_form_group_errors(browser, index=0)

        browser.type(XPath.input_labelled('Some input'), '')
        browser.click(XPath.button_labelled('Submit'))

        assert ['is-invalid'
                ] == fixture.get_form_group_highlight_marks(browser, index=0)
        [error] = fixture.get_form_group_errors(browser, index=0)
        assert error.text == 'Some input is required'

        browser.type(XPath.input_labelled('Some input'), 'valid value')
        browser.click(XPath.button_labelled('Submit'))

        assert ['is-valid'] == fixture.get_form_group_highlight_marks(browser,
                                                                      index=0)
        assert not fixture.get_form_group_errors(browser, index=0)

        browser.type(XPath.input_labelled('Another input'), 'valid value')
        browser.click(XPath.button_labelled('Submit'))

        assert not fixture.get_form_group_highlight_marks(browser, index=0)
        assert not fixture.get_form_group_errors(browser, index=0)
コード例 #18
0
def test_edit_and_add_own(web_fixture, access_domain_fixture,
                          access_ui_fixture):
    """The owner of an AddressBook can add and edit Addresses to the owned AddressBook."""

    browser = access_ui_fixture.browser
    fixture = access_domain_fixture
    account = fixture.account
    address_book = fixture.address_book

    web_fixture.log_in(browser=browser, system_account=account)
    browser.open('/')

    browser.click(XPath.link().with_text('Address book of [email protected]'))

    # add
    browser.click(XPath.link().with_text('Add address'))
    browser.type(XPath.input_labelled('Name'), 'Someone')
    browser.type(XPath.input_labelled('Email'), '*****@*****.**')
    browser.click(XPath.button_labelled('Save'))

    assert browser.is_element_present(
        XPath.paragraph().including_text('Someone: [email protected]'))

    # edit
    browser.click(XPath.button_labelled('Edit'))
    browser.type(XPath.input_labelled('Name'), 'Else')
    browser.type(XPath.input_labelled('Email'), '*****@*****.**')
    browser.click(XPath.button_labelled('Update'))

    assert browser.is_element_present(
        XPath.paragraph().including_text('Else: [email protected]'))
コード例 #19
0
def test_register_help_pending(web_fixture, party_account_fixture,
                               accounts_web_fixture):
    fixture = accounts_web_fixture

    verification_requests = Session.query(VerifyEmailRequest)
    unactivated_account = party_account_fixture.new_system_account(
        email='*****@*****.**', activated=False)
    activation_request = VerifyEmailRequest(
        email=unactivated_account.email,
        subject_config='accounts.activation_subject',
        email_config='accounts.activation_email')
    Session.add(activation_request)
    deferred_activation = ActivateAccount(system_account=unactivated_account,
                                          requirements=[activation_request])
    Session.add(deferred_activation)

    fixture.browser.open('/a_ui/registerHelp')
    fixture.browser.type(XPath.input_labelled('Email'),
                         unactivated_account.email)
    fixture.browser.click(XPath.button_labelled('Investigate'))

    assert fixture.browser.current_url.path == '/a_ui/registerHelp/pending'
    assert verification_requests.count() == 1
    party_account_fixture.mailer.reset()
    fixture.browser.click(XPath.button_labelled('Send'))

    assert verification_requests.count() == 1
    assert party_account_fixture.mailer.mail_sent
    assert fixture.browser.current_url.path == '/a_ui/registerHelp/pending/sent'
コード例 #20
0
def test_simple_file_input_exceptions(web_fixture):
    """Usually, when a DomainException happens during a form submit Inputs save the input they received so that
       such input can be pre-populated on the screen rendered by a subsequent GET for a user to correct
       possible mistakes and resubmit.

       In the case of a SimpleFileInput however, the UploadedFile objects that serve as user input
       to a SimpleFileInput are discarded when a DomainException happens.  This is because it is not
       possible to prepopulate its value using HTML or JS as this would be a security risk.
    """

    file_to_upload = temp_file_with('some content')
    failing_constraint = FailingConstraint('I am breaking')

    class DomainObject(object):
        def __init__(self):
            self.file = None

        @exposed
        def fields(self, fields):
            fields.file = FileField(allow_multiple=False,
                                    label='Attached files')
            # FailingConstraint is declared in module level scope for it to be pickleable
            fields.file.add_validation_constraint(failing_constraint)

        @exposed
        def events(self, events):
            events.upload = Event(label='Upload')

    domain_object = DomainObject()

    class FileUploadForm(Form):
        def __init__(self, view):
            super(FileUploadForm, self).__init__(view, 'test')
            file_input = self.add_child(
                SimpleFileInput(self, domain_object.fields.file))
            if file_input.validation_error:
                self.add_child(self.create_error_label(file_input))
            self.define_event_handler(domain_object.events.upload)
            self.add_child(ButtonInput(self, domain_object.events.upload))

    wsgi_app = web_fixture.new_wsgi_app(child_factory=FileUploadForm.factory(),
                                        enable_js=False)
    web_fixture.reahl_server.set_app(wsgi_app)

    browser = web_fixture.driver_browser
    browser.open('/')

    browser.type(XPath.input_of_type('file'), file_to_upload.name)
    browser.click(XPath.button_labelled('Upload'))
    assert browser.is_element_present('//label[text()="I am breaking"]')

    # Message is cleared on second attempt
    failing_constraint.fail = False
    browser.type(XPath.input_of_type('file'), file_to_upload.name)
    browser.click(XPath.button_labelled('Upload'))
    assert not browser.is_element_present('//label[text()="I am breaking"]')
コード例 #21
0
ファイル: test_form.py プロジェクト: xmonader/reahl
def test_alert_for_domain_exception(web_fixture):
    """FormLayout can be used to add an Alert with error messages to a form. This includes a 'Reset input'
       button which clears the form input.
    """
    class ModelObject:
        @exposed
        def fields(self, fields):
            fields.some_field = Field(label='Some field',
                                      default='not changed')

        @exposed
        def events(self, events):
            events.submit_break = Event(label='Submit',
                                        action=Action(self.always_break))

        def always_break(self):
            raise DomainException('designed to break')

    class MyForm(Form):
        def __init__(self, view):
            super().__init__(view, 'myform')
            self.use_layout(FormLayout())
            model_object = ModelObject()

            if self.exception:
                self.layout.add_alert_for_domain_exception(self.exception)

            self.layout.add_input(
                TextInput(self, model_object.fields.some_field))

            self.define_event_handler(model_object.events.submit_break)
            self.add_child(Button(self, model_object.events.submit_break))

    wsgi_app = web_fixture.new_wsgi_app(child_factory=MyForm.factory())
    web_fixture.reahl_server.set_app(wsgi_app)
    browser = web_fixture.driver_browser

    browser.open('/')

    browser.type(XPath.input_labelled('Some field'), 'some input given')
    browser.click(XPath.button_labelled('Submit'))

    alert = XPath.div().including_class('alert')

    assert browser.is_element_present(alert)
    assert browser.get_text(alert) == 'An error occurred: DomainException'

    assert browser.get_value(
        XPath.input_labelled('Some field')) == 'some input given'
    browser.click(XPath.button_labelled('Reset input'))

    assert not browser.is_element_present(alert)
    assert browser.get_value(
        XPath.input_labelled('Some field')) == 'not changed'
コード例 #22
0
def test_example(web_fixture, responsive_example_fixture):
    fixture = responsive_example_fixture

    wsgi_application = web_fixture.new_wsgi_app(site_root=ResponsiveUI,
                                                enable_js=True)
    web_fixture.reahl_server.set_app(wsgi_application)

    browser = fixture.browser

    browser.open('/')

    # Reveal sections for new investors
    assert not browser.is_visible(fixture.investor_information)
    browser.set_selected(XPath.input_labelled('New'))

    browser.wait_for_element_visible(fixture.investor_information)
    browser.wait_for_element_visible(fixture.new_investor_specific_information)

    # Reveal and complete sections for existing investors
    browser.set_selected(XPath.input_labelled('Existing'))

    browser.wait_for_element_visible(fixture.investor_information)
    browser.wait_for_element_not_visible(
        fixture.new_investor_specific_information)

    browser.type(XPath.input_labelled('Existing account number'), '1234')

    # Reveal sections for Investment allocation details
    assert not browser.is_visible(fixture.investment_allocation_details)

    browser.click(
        XPath.label().with_text('I agree to the terms and conditions'))
    browser.wait_for_element_visible(fixture.investment_allocation_details)

    browser.type(XPath.input_labelled('Total amount'), '10000')

    # Check calculating totals
    browser.type(fixture.percentage_input_for('Fund A'), '80')
    browser.wait_for(fixture.percentage_total_is, '80')

    browser.type(fixture.percentage_input_for('Fund B'), '80')
    browser.wait_for(fixture.percentage_total_is, '160')

    # Check DomainException upon submit with incorrect totals
    browser.click(XPath.button_labelled('Submit'))
    browser.wait_for_element_visible(fixture.domain_exception_alert)

    browser.type(fixture.percentage_input_for('Fund B'), '20')
    browser.wait_for(fixture.percentage_total_is, '100')

    # Check successful submit
    browser.click(XPath.button_labelled('Submit'))
    browser.wait_for_element_not_visible(fixture.domain_exception_alert)
コード例 #23
0
ファイル: test_files.py プロジェクト: xmonader/reahl
def test_file_upload_input_basics(web_fixture, file_upload_input_fixture):
    """A FileUploadInput allows its user to upload multiple files one by one before the Form that
       contains the FileUploadInput is submitted.  When the Form is finally submitted
       the FileField of the FileUploadInput receives all the files uploaded as UploadFile objects.
    """
    fixture = file_upload_input_fixture

    web_fixture.reahl_server.set_app(fixture.wsgi_app)

    browser = web_fixture.driver_browser
    browser.open('/')

    assert not fixture.domain_object.submitted
    assert not fixture.file_was_uploaded(fixture.file_to_upload1.name)
    assert not fixture.file_was_uploaded(fixture.file_to_upload2.name)

    # Upload one file
    browser.type(XPath.input_labelled('Choose file(s)'),
                 fixture.file_to_upload1.name)
    browser.click(XPath.button_labelled('Upload'))

    assert not fixture.domain_object.submitted
    assert fixture.file_was_uploaded(fixture.file_to_upload1.name)
    assert not fixture.file_was_uploaded(fixture.file_to_upload2.name)

    # Upload a second file
    browser.type(XPath.input_labelled('Choose file(s)'),
                 fixture.file_to_upload2.name)
    browser.click(XPath.button_labelled('Upload'))

    assert not fixture.domain_object.submitted
    assert fixture.file_was_uploaded(fixture.file_to_upload1.name)
    assert fixture.file_was_uploaded(fixture.file_to_upload2.name)

    # Submit the form
    browser.click(XPath.button_labelled('Submit'))
    assert fixture.domain_object.submitted

    # All uploaded files were submitted
    assert sorted(fixture.domain_object.submitted_file_info.keys()) == sorted([
        os.path.basename(f.name)
        for f in [fixture.file_to_upload1, fixture.file_to_upload2]
    ])

    # Files that were submitted are correct
    file1_content, file1_mime_type = fixture.domain_object.submitted_file_info[
        os.path.basename(fixture.file_to_upload1.name)]
    assert file1_content == fixture.file_to_upload1_content
    assert file1_mime_type == 'text/html'
コード例 #24
0
def test_see_other(web_fixture, access_domain_fixture, access_ui_fixture):
    """If allowed, an account may see another account's AddressBook, and could edit or add Addresses,
       depending on the allowed rights."""

    browser = access_ui_fixture.browser
    account = access_domain_fixture.account
    address_book = access_domain_fixture.address_book

    other_address_book = access_domain_fixture.other_address_book
    other_address_book.allow(account)
    Address(address_book=other_address_book,
            email_address='*****@*****.**',
            name='Friend').save()

    web_fixture.log_in(browser=browser, system_account=account)
    browser.open('/')

    browser.click(XPath.link().with_text('Address book of [email protected]'))

    assert browser.is_element_present(
        XPath.paragraph().including_text('Friend: [email protected]'))

    # Case: can only see
    assert not browser.is_element_enabled(
        XPath.link().with_text('Add address'))
    assert not browser.is_element_enabled(XPath.button_labelled('Edit'))

    # Case: can edit only
    other_address_book.allow(account,
                             can_edit_addresses=True,
                             can_add_addresses=False)
    browser.refresh()
    assert not browser.is_element_enabled(
        XPath.link().with_text('Add address'))
    assert browser.is_element_enabled(XPath.button_labelled('Edit'))

    # Case: can add, and therefor also edit
    other_address_book.allow(account, can_add_addresses=True)
    browser.refresh()
    assert browser.is_element_enabled(XPath.link().with_text('Add address'))
    assert browser.is_element_enabled(XPath.button_labelled('Edit'))

    browser.click(XPath.button_labelled('Edit'))
    browser.type(XPath.input_labelled('Name'), 'Else')
    browser.type(XPath.input_labelled('Email'), '*****@*****.**')
    browser.click(XPath.button_labelled('Update'))

    assert browser.is_element_present(
        XPath.paragraph().including_text('Else: [email protected]'))
コード例 #25
0
ファイル: test_popup.py プロジェクト: smohaorg/reahl
def test_workings_of_check_checkbox_button(web_fixture, popup_a_fixture):
    """A CheckCheckBoxButton checks the checkbox on the original page when clicked."""
    class PopupTestPanel(Div):
        @exposed
        def fields(self, fields):
            fields.field = BooleanField(label='a checkbox')

        def __init__(self, view):
            super().__init__(view)
            popup_a = self.add_child(
                PopupA(view, view.as_bookmark(), '#contents'))
            popup_contents = self.add_child(
                P(view, text='this is the content of the popup'))
            popup_contents.set_id('contents')
            form = self.add_child(Form(view, 'aform')).use_layout(FormLayout())
            checkbox = form.layout.add_input(
                CheckboxInput(form, self.fields.field))

            popup_a.add_js_button('Checkit', CheckCheckboxScript(checkbox))

    wsgi_app = web_fixture.new_wsgi_app(enable_js=True,
                                        child_factory=PopupTestPanel.factory())
    web_fixture.reahl_server.set_app(wsgi_app)
    browser = web_fixture.driver_browser
    browser.open('/')

    browser.click(XPath.link().with_text('Home page'))
    browser.wait_for(popup_a_fixture.is_popped_up)

    browser.click(XPath.button_labelled('Checkit'))
    browser.wait_for_not(popup_a_fixture.is_popped_up)

    assert browser.is_selected(XPath.input_labelled('a checkbox'))
コード例 #26
0
ファイル: test_files.py プロジェクト: xmonader/reahl
def test_prevent_duplicate_upload_js(web_fixture, file_upload_input_fixture):
    """The user is prevented from uploading more than one file with the same name on the client side.
    """

    fixture = file_upload_input_fixture

    web_fixture.reahl_server.set_app(fixture.new_wsgi_app(enable_js=True))
    browser = web_fixture.driver_browser

    error_locator = XPath.span().including_text(
        'uploaded files should all have different names')

    def error_is_visible():
        return browser.is_visible(error_locator)

    browser.open('/')

    browser.type(XPath.input_labelled('Choose file(s)'),
                 fixture.file_to_upload1.name)
    browser.wait_for_not(error_is_visible)

    browser.type(XPath.input_labelled('Choose file(s)'),
                 fixture.file_to_upload2.name)
    browser.wait_for_not(error_is_visible)

    with web_fixture.reahl_server.paused():
        browser.type(XPath.input_labelled('Choose file(s)'),
                     fixture.file_to_upload1.name)
        assert not fixture.upload_file_is_queued(fixture.file_to_upload1.name)
        browser.wait_for(error_is_visible)

    browser.click(
        XPath.button_labelled('Remove', filename=fixture.file_to_upload2_name))
    browser.wait_for_not(error_is_visible)
コード例 #27
0
ファイル: test_files.py プロジェクト: xmonader/reahl
def test_async_in_progress(web_fixture, large_file_upload_input_fixture):
    """While a large file is being uploaded, a progress bar and a Cancel button are displayed. Clicking on the Cancel
       button stops the upload and clears the file name from the list of uploaded files.
    """
    fixture = large_file_upload_input_fixture

    fixture.run_hook_before = True
    web_fixture.reahl_server.set_app(fixture.new_wsgi_app(enable_js=True))

    browser = web_fixture.driver_browser
    browser.open('/')

    assert not fixture.file_was_uploaded(fixture.file_to_upload1.name)
    assert not fixture.uploaded_file_is_listed(fixture.file_to_upload1.name)

    with web_fixture.reahl_server.in_background(wait_till_done_serving=False):
        browser.type(XPath.input_labelled('Choose file(s)'),
                     fixture.file_to_upload1.name,
                     wait_for_ajax=False)  # Upload will block, see fixture

    assert browser.is_element_present('//ul/li/progress')
    progress = browser.get_attribute('//ul/li/progress', 'value')
    assert progress == '100'
    browser.click(XPath.button_labelled('Cancel'), wait_for_ajax=False)

    assert not fixture.uploaded_file_is_listed(fixture.file_to_upload1.name)
    assert not fixture.file_was_uploaded(fixture.file_to_upload1.name)
コード例 #28
0
ファイル: test_popup.py プロジェクト: smohaorg/reahl
def test_default_behaviour(web_fixture, popup_a_fixture):
    """If you click on the A, a popupwindow opens with its contents the specified
       element on the target page."""
    class PopupTestPanel(Div):
        def __init__(self, view):
            super().__init__(view)
            self.add_child(PopupA(view, view.as_bookmark(), '#contents'))
            popup_contents = self.add_child(
                P(view, text='this is the content of the popup'))
            popup_contents.set_id('contents')

    wsgi_app = web_fixture.new_wsgi_app(enable_js=True,
                                        child_factory=PopupTestPanel.factory())
    web_fixture.reahl_server.set_app(wsgi_app)
    browser = web_fixture.driver_browser
    browser.open('/')

    # The A is rendered correctly
    assert browser.is_element_present(
        "//a[@title='Home page' and text()='Home page' and @href='/']")

    # subsequent behaviour
    browser.click(XPath.link().with_text('Home page'))
    browser.wait_for(popup_a_fixture.is_popped_up)

    #check some bootstrap attributes
    dialog_xpath = "//div[@class='modal fade show' and @tabindex='-1']/div[@class='modal-dialog']/div[@class='modal-content']"
    assert browser.is_element_present(dialog_xpath)

    browser.click(XPath.button_labelled('Close'))
    browser.wait_for_not(popup_a_fixture.is_popped_up)
コード例 #29
0
def test_deleting_several_address(web_fixture, fixture):
    """To delete several address, a user "checks" the box next to each of the Addresses
       on the "Addresses" page she wants to delete. Upon clicking the "Delete Selected" Button, the page
       refreshes, and the remaining addresses appear."""

    fixture.create_addresses()  #create some data to play with

    web_fixture.reahl_server.set_app(
        web_fixture.new_wsgi_app(site_root=AddressBookUI))

    fixture.browser = web_fixture.driver_browser
    fixture.browser.open('/')

    name_of_address_1 = 'friend 1'
    name_of_address_13 = 'friend 13'
    name_of_address_20 = 'friend 20'

    assert fixture.address_is_listed_as(name_of_address_1)
    assert fixture.address_is_listed_as(name_of_address_13)
    assert fixture.address_is_listed_as(name_of_address_20)

    fixture.browser.click(XPath.checkbox().inside_of(
        XPath.table_row()[1].inside_of(XPath.table_body())))
    fixture.browser.click(XPath.checkbox().inside_of(
        XPath.table_row()[13].inside_of(XPath.table_body())))
    fixture.browser.click(XPath.checkbox().inside_of(
        XPath.table_row()[20].inside_of(XPath.table_body())))
    fixture.browser.click(XPath.button_labelled('Delete Selected'))

    assert fixture.is_on_home_page()
    assert not fixture.address_is_listed_as(name_of_address_1)
    assert not fixture.address_is_listed_as(name_of_address_13)
    assert not fixture.address_is_listed_as(name_of_address_20)
コード例 #30
0
def test_add_collaborator(web_fixture, access_domain_fixture,
                          access_ui_fixture):
    """A user may add other users as collaborators to his address book, specifying the privileges in the process."""

    browser = access_ui_fixture.browser
    address_book = access_domain_fixture.address_book
    account = access_domain_fixture.account

    other_address_book = access_domain_fixture.other_address_book
    other_account = access_domain_fixture.other_account

    web_fixture.log_in(browser=browser, system_account=account)
    browser.open('/')

    assert address_book not in AddressBook.address_books_visible_to(
        other_account)
    assert not address_book.can_be_edited_by(other_account)
    assert not address_book.can_be_added_to_by(other_account)

    browser.click(XPath.link().with_text('Address book of [email protected]'))
    browser.click(XPath.link().with_text('Add collaborator'))

    browser.select(XPath.select_labelled('Choose collaborator'),
                   '*****@*****.**')
    browser.click(XPath.input_labelled('May add new addresses'))
    browser.click(XPath.input_labelled('May edit existing addresses'))

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

    assert access_ui_fixture.is_on_address_book_page_of('*****@*****.**')

    assert address_book in AddressBook.address_books_visible_to(other_account)
    assert address_book.can_be_edited_by(other_account)
    assert address_book.can_be_added_to_by(other_account)