예제 #1
0
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]'))
예제 #2
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')) == ''
예제 #3
0
def test_correct_tab_order_for_responsive_widgets(web_fixture, disclosed_input_trigger_fixture):
    """When a user TAB's out of an input that then triggers a change, the tab is ignored and focus stays on the original input so that the tab order can be recalculated."""

    fixture = disclosed_input_trigger_fixture
    fixture.trigger_input_type = TextInput
    fixture.default_trigger_field_value = False

    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
    browser.open('/')

    # Case: a new input appears in next tab order position
    assert browser.get_value(XPath.input_labelled('Trigger field')) == 'off'
    browser.press_tab()
    assert browser.is_focus_on(XPath.input_labelled('Trigger field'))
    browser.type(XPath.input_labelled('Trigger field'), 'on', trigger_blur=False, wait_for_ajax=False)
    browser.press_tab()
    browser.press_tab()
    assert browser.is_focus_on(XPath.input_labelled('Email'))
    
    # Case: an input disappears from the next tab order position
    browser.type(XPath.input_labelled('Trigger field'), 'off', trigger_blur=False, wait_for_ajax=False)
    browser.press_tab()
    browser.press_tab()
    assert browser.is_focus_on(XPath.button_labelled('click me'))
예제 #4
0
def test_required_constraint_js(web_fixture, constraint_rendering_fixture):
    fixture = constraint_rendering_fixture

    constraint = RequiredConstraint()

    class MyForm(Form):
        def __init__(self, view, name):
            super().__init__(view, name)
            self.use_layout(FormLayout())
            field = fixture.model_object.fields.an_attribute.with_validation_constraint(constraint)
            self.layout.add_input(TextInput(self, field))
    wsgi_app = web_fixture.new_wsgi_app(child_factory=MyForm.factory('myform'), enable_js=True)
    web_fixture.reahl_server.set_app(wsgi_app)

    web_fixture.driver_browser.open('/')

    web_fixture.driver_browser.type(XPath.input_labelled('an attribute'), 'something', trigger_blur=False, wait_for_ajax=False)
    web_fixture.driver_browser.press_tab()
    web_fixture.driver_browser.wait_for_element_not_visible(fixture.error_xpath)

    web_fixture.driver_browser.type(XPath.input_labelled('an attribute'), '')
    
    web_fixture.driver_browser.press_keys(web_fixture.driver_browser.Keys.BACK_SPACE, locator=XPath.input_labelled('an attribute'))  # To trigger validation on the field

    web_fixture.driver_browser.wait_for_element_visible(fixture.error_xpath)
예제 #5
0
def test_input_values_retained_upon_domain_exception(web_fixture, disclosed_input_fixture):
    """When a domain exception occurs the values typed into an input are retained on the error page."""
    # Note: the implementation of this is different for dynamic stuff than for plain old forms.
    #
    # Client state is maintained (for a subsequent GET) by posting it to the server in a hidden input; and also saved on an exception.
    # This state is used at Widget construction stage (before the POST is handled) to ensure all Widgets on the View are built as 
    # before, and as per the client state.
    # 
    # This test is about how that state is managed and when which version of the state (saved in DB, POSTed etc) takes precedence.

    fixture = disclosed_input_fixture

    fixture.raise_domain_exception_on_submit = True
    fixture.default_trigger_field_value = False

    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
    browser.open('/')

    assert not browser.is_element_present(XPath.input_labelled('Email'))
    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'))
    assert browser.is_selected(XPath.input_labelled('Trigger field'))
    assert browser.get_value(XPath.input_labelled('Email')) == '*****@*****.**'
예제 #6
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)
예제 #7
0
파일: test_input.py 프로젝트: dli7428/reahl
def test_marshalling_of_radio_button_select_input(web_fixture, input_fixture, field_scenario):
    """When a form is submitted, the value of the selected radio button is persisted."""

    fixture = input_fixture
    choices = [Choice(1, IntegerField(label='One')),
               Choice(2, IntegerField(label='Two'))]
    fixture.field = field_scenario.field_class(choices)

    model_object = fixture.model_object
    model_object.an_attribute = field_scenario.default_domain_value

    wsgi_app = web_fixture.new_wsgi_app(child_factory=fixture.new_Form(input_widget_class=RadioButtonSelectInput).factory('myform'))
    web_fixture.reahl_server.set_app(wsgi_app)
    web_fixture.driver_browser.open('/')

    radio_one = XPath.input_labelled('One')
    radio_two = XPath.input_labelled('Two')
    # One is pre selected
    assert web_fixture.driver_browser.is_selected(radio_one)
    assert not web_fixture.driver_browser.is_selected(radio_two)

    # click on Two
    web_fixture.driver_browser.click(radio_two)
    assert not web_fixture.driver_browser.is_selected(radio_one)

    web_fixture.driver_browser.click(XPath.button_labelled('click me'))

    assert model_object.an_attribute == field_scenario.selected_domain_value
예제 #8
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))
예제 #9
0
파일: test_files.py 프로젝트: dli7428/reahl
def test_async_number_files_validation(web_fixture, max_number_of_files_file_upload_input_fixture):
    """A Field set to only allow a maximum number of files is checked for validity before uploading in JS.
    """
    # Only tested for the FileUploadInput, as it uses the FileInput
    # in its own implementation, in a NestedForm, and has to pass on the
    # filesize constraint all the way. This way, we test all of that.
    fixture = max_number_of_files_file_upload_input_fixture

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

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

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

    browser.type(XPath.input_labelled('Choose file(s)'), fixture.file_to_upload1.name)
    assert fixture.uploaded_file_is_listed( fixture.file_to_upload1.name ) 
    # Corner case: max are uploaded, but you've not asked to add to them yet:
    assert browser.wait_for_not(browser.is_visible, XPath.span().including_text('a maximum of 1 files may be uploaded')) 

    # Normal case: max are uploaded, and you're asking to upload another:
    browser.type(XPath.input_labelled('Choose file(s)'), fixture.file_to_upload2.name)
    assert not fixture.uploaded_file_is_listed( fixture.file_to_upload2.name ) 
    assert browser.wait_for(browser.is_visible, XPath.span().including_text('a maximum of 1 files may be uploaded')) 

    browser.click(XPath.button_labelled('Remove', filename=fixture.file_to_upload1_name))
    assert browser.wait_for_not(browser.is_visible, XPath.span().including_text('a maximum of 1 files may be uploaded')) 
예제 #10
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)
예제 #11
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))
예제 #12
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()) == [] 
예제 #13
0
파일: test_files.py 프로젝트: dli7428/reahl
def test_cancelling_queued_upload(web_fixture, large_file_upload_input_fixture):
    """Cancelling an upload that is still queued (upload not started yet) removes the file from the list
       and removed it from the queue of uploads.
    """
    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 ) 
    assert not fixture.file_was_uploaded( fixture.file_to_upload2.name ) 
    assert not fixture.uploaded_file_is_listed( fixture.file_to_upload2.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
        browser.type(XPath.input_labelled('Choose file(s)'), fixture.file_to_upload2.name, wait_for_ajax=False) # Upload will block, see fixture

    browser.wait_for(fixture.upload_file_is_queued, fixture.file_to_upload1.name)
    browser.wait_for(fixture.upload_file_is_queued, fixture.file_to_upload2.name)

    browser.click(XPath.button_labelled('Cancel', filename=fixture.file_to_upload2_name), wait_for_ajax=False)

    browser.wait_for_not(fixture.upload_file_is_queued, fixture.file_to_upload2.name)
    fixture.simulate_large_file_upload_done()
    browser.wait_for(fixture.uploaded_file_is_listed, fixture.file_to_upload1.name)

    assert fixture.uploaded_file_is_listed( fixture.file_to_upload1.name ) 
    assert fixture.file_was_uploaded( fixture.file_to_upload1.name ) 
    assert not fixture.uploaded_file_is_listed( fixture.file_to_upload2.name ) 
    assert not fixture.file_was_uploaded( fixture.file_to_upload2.name ) 
예제 #14
0
def test_verify_from_menu(web_fixture, party_account_fixture,
                          accounts_web_fixture):
    fixture = accounts_web_fixture

    account = party_account_fixture.new_system_account(activated=False)
    activation_request = VerifyEmailRequest(
        email=account.email,
        subject_config='accounts.activation_subject',
        email_config='accounts.activation_email')
    Session.add(activation_request)
    deferred_activation = ActivateAccount(system_account=account,
                                          requirements=[activation_request])
    Session.add(deferred_activation)
    secret_key = activation_request.as_secret_key()

    assert not account.status.is_active()
    fixture.browser.open('/a_ui/verify')

    fixture.browser.type(XPath.input_labelled('Email'), account.email)
    fixture.browser.type(XPath.input_labelled('Secret key'), secret_key)
    fixture.browser.type(XPath.input_labelled('Password'), account.password)
    fixture.browser.click(XPath.button_labelled('Verify'))

    assert fixture.browser.current_url.path == '/a_ui/thanks'
    assert account.status.is_active()
예제 #15
0
def cue_input_display_basics(fixture):
    """A CueInput displays a given cue when its wrapped Input has focus and hides the cue otherwise."""
    class FormWithCueInput(Form):
        def __init__(self, view):
            super(FormWithCueInput, self).__init__(view, 'test')
            self.use_layout(FormLayout())
            cue_input = CueInput(
                TextInput(self, fixture.domain_object.fields.field),
                P(view, 'this is your cue'))
            self.layout.add_input(cue_input)

    wsgi_app = fixture.new_wsgi_app(child_factory=FormWithCueInput.factory(),
                                    enable_js=True)

    fixture.reahl_server.set_app(wsgi_app)
    browser = fixture.driver_browser
    browser.open('/')

    #initially the cue is not visible
    browser.wait_for_element_not_visible(fixture.cue_element_xpath)
    #tabbing to the input reveals the cue
    browser.focus_on(XPath.input_labelled('MyField'))
    browser.wait_for_element_visible(fixture.cue_element_xpath)

    #moving focus to another input causes the cue to be hidden
    browser.press_tab(XPath.input_labelled('MyField'))
    browser.wait_for_element_not_visible(fixture.cue_element_xpath)
예제 #16
0
파일: test_input.py 프로젝트: dli7428/reahl
def test_marshalling_of_checkbox_select_input(web_fixture, checkbox_fixture):
    """CheckboxSelectInput is used to choose many things from a list."""

    fixture = checkbox_fixture
    choices = [Choice(1, IntegerField(label='One')),
               Choice(2, IntegerField(label='Two')),
               Choice(3, IntegerField(label='Three'))]
    fixture.field = MultiChoiceField(choices)

    model_object = fixture.model_object
    model_object.an_attribute = [1]
    wsgi_app = web_fixture.new_wsgi_app(child_factory=fixture.new_Form(input_widget_class=CheckboxSelectInput).factory('myform'))
    web_fixture.reahl_server.set_app(wsgi_app)
    web_fixture.driver_browser.open('/')

    assert web_fixture.driver_browser.is_selected(XPath.input_labelled('One'))
    assert not web_fixture.driver_browser.is_selected(XPath.input_labelled('Two'))
    assert not web_fixture.driver_browser.is_selected(XPath.input_labelled('Three'))

    # Case: checkbox is submitted with form (ie checked)
    web_fixture.driver_browser.set_deselected(XPath.input_labelled('One'))
    web_fixture.driver_browser.set_selected(XPath.input_labelled('Two'))
    web_fixture.driver_browser.set_selected(XPath.input_labelled('Three'))
    web_fixture.driver_browser.click(XPath.button_labelled('click me'))

    assert model_object.an_attribute == [2, 3]
    assert fixture.checkbox.value == '2,3'
    assert not web_fixture.driver_browser.is_selected(XPath.input_labelled('One'))
    assert web_fixture.driver_browser.is_selected(XPath.input_labelled('Two'))
    assert web_fixture.driver_browser.is_selected(XPath.input_labelled('Three'))