def dropdown_menus(fixture): """You can add a DropdownMenu as a dropdown inside a Nav.""" menu = Nav(fixture.view) sub_menu = DropdownMenu(fixture.view) sub_menu.add_a(A(fixture.view, Url('/an/url'), description='sub menu item')) menu.add_dropdown('Dropdown title', sub_menu) [item] = menu.html_representation.children vassert(item.tag_name == 'li') vassert('dropdown' in item.get_attribute('class')) [toggle, added_sub_menu] = item.children vassert('dropdown-toggle' in toggle.get_attribute('class')) vassert('dropdown' in toggle.get_attribute('data-toggle')) vassert('-' in toggle.get_attribute('data-target')) vassert('caret' in toggle.children[1].get_attribute('class')) title_text = toggle.children[0].value vassert(title_text == 'Dropdown title') vassert(added_sub_menu is sub_menu) vassert('dropdown-menu' in added_sub_menu.html_representation.get_attribute('class').split()) vassert(isinstance(added_sub_menu.html_representation, Div)) [dropdown_item] = added_sub_menu.html_representation.children vassert(isinstance(dropdown_item, A)) vassert('dropdown-item' in dropdown_item.get_attribute('class').split())
def test_dropdown_menus(web_fixture): """You can add a DropdownMenu as a dropdown inside a Nav.""" menu = Nav(web_fixture.view) sub_menu = DropdownMenu(web_fixture.view) sub_menu.add_a(A(web_fixture.view, Url('/an/url'), description='sub menu item')) menu.add_dropdown('Dropdown title', sub_menu) [item] = menu.html_representation.children assert item.tag_name == 'li' assert 'dropdown' in item.get_attribute('class') [toggle, added_sub_menu] = item.children assert 'dropdown-toggle' in toggle.get_attribute('class') assert 'button' in toggle.get_attribute('role') assert 'true' in toggle.get_attribute('aria-haspopup') assert 'dropdown' in toggle.get_attribute('data-toggle') title_text = toggle.children[0].value assert title_text == 'Dropdown title' assert added_sub_menu is sub_menu assert 'dropdown-menu' in added_sub_menu.html_representation.get_attribute('class').split() assert isinstance(added_sub_menu.html_representation, Div) [dropdown_item] = added_sub_menu.html_representation.children assert isinstance(dropdown_item, A) assert 'dropdown-item' in dropdown_item.get_attribute('class').split()
def test_nav_layouts(web_fixture, layout_scenarios): """Navs can be laid out in different ways.""" menu = Nav(web_fixture.view) assert not layout_scenarios.layout_css_class.issubset(menu.html_representation.attributes['class'].value) menu.use_layout(layout_scenarios.layout) assert layout_scenarios.layout_css_class.issubset(menu.html_representation.attributes['class'].value)
def __init__(self, view): super(AddressBookPage, self).__init__(view) self.use_layout(PageLayout(document_layout=Container())) contents_layout = ColumnLayout(('secondary', ResponsiveSize(md=3)), ('main', ResponsiveSize(md=9))).with_slots() self.layout.contents.use_layout(contents_layout) nav = Nav(view).use_layout(PillLayout(stacked=True)) contents_layout.columns['secondary'].add_child(nav.with_languages())
def test_nav_layouts_can_be_used_to_align_items_horizontally(web_fixture, different_layout_types): """Both a PillLayout or TabLayout can be set to make the MenuItems of their Nav be aligned horizontal.""" menu = Nav(web_fixture.view).use_layout(different_layout_types.layout_class()) assert 'justify-content-center' not in menu.html_representation.get_attribute('class') menu = Nav(web_fixture.view).use_layout(different_layout_types.layout_class(content_alignment='center')) assert 'justify-content-center' in menu.html_representation.get_attribute('class')
def test_nav_layouts_can_be_used_to_fill_available_space(web_fixture, different_layout_types): """Both a PillLayout or TabLayout can be set to make the MenuItems of their Nav fill the width of the parent""" menu = Nav(web_fixture.view).use_layout(different_layout_types.layout_class()) assert 'nav-justified' not in menu.html_representation.get_attribute('class') menu = Nav(web_fixture.view).use_layout(different_layout_types.layout_class(content_justification='justified')) assert 'nav-justified' in menu.html_representation.get_attribute('class')
def justified_items(fixture): """Both a PillLayout or TabLayout can be set to make the MenuItems of their Nav fill the width of the parent, with the text of each item centered.""" menu = Nav(fixture.view).use_layout(fixture.layout_type()) vassert( 'nav-justified' not in menu.html_representation.get_attribute('class')) menu = Nav(fixture.view).use_layout(fixture.layout_type(justified=True)) vassert('nav-justified' in menu.html_representation.get_attribute('class'))
def nav_layouts(fixture): """Navs can be laid out in different ways.""" menu = Nav(fixture.view) vassert(not fixture.layout_css_class.issubset( menu.html_representation.attributes['class'].value)) menu.use_layout(fixture.layout) vassert( fixture.layout_css_class.issubset( menu.html_representation.attributes['class'].value))
def dropdown_menus_can_drop_up(fixture): """Dropdown menus can drop upwards instead of downwards.""" menu = Nav(fixture.view) sub_menu = Nav(fixture.view) menu.add_dropdown('Dropdown title', sub_menu, drop_up=True) [item] = menu.html_representation.children vassert(item.tag_name == 'li') vassert('dropup' in item.get_attribute('class'))
def test_dropdown_menus_drop_positions(web_fixture, drop_position_fixture): """Dropdown menus can drop to many positions.""" menu = Nav(web_fixture.view) sub_menu = Nav(web_fixture.view) menu.add_dropdown('Dropdown title', sub_menu, drop_position=drop_position_fixture.direction) [item] = menu.html_representation.children assert item.tag_name == 'li' assert drop_position_fixture.expected_class in item.get_attribute('class')
def test_rendering_active_menu_items(web_fixture, menu_item_scenarios): """A MenuItem is marked as active based on its active_regex or the A it represents.""" description = 'The link' href = Url('/link') menu = Nav(web_fixture.view) menu_item_a = A(web_fixture.view, href, description=description) menu.add_a(menu_item_a, active_regex=menu_item_scenarios.active_regex) tester = WidgetTester(menu) actual = tester.get_html_for('//li') active_str = '' if not menu_item_scenarios.active else 'active ' expected_menu_item_html = '<li class="nav-item"><a href="/link" class="%snav-link">The link</a></li>' % (active_str) assert actual == expected_menu_item_html
def __init__(self, view, address_book, address_book_ui): self.address_book = address_book super(AddressBookPanel, self).__init__(view) self.add_child(H(view, 1, text='Addresses in %s' % address_book.display_name)) self.add_child(Nav(view).use_layout(TabLayout()).with_bookmarks(self.menu_bookmarks(address_book_ui))) self.add_children([AddressBox(view, address) for address in address_book.addresses])
def __init__(self, view, funding_request, apply_bookmark): super(FundingRequestSummary, self).__init__(view) self.add_child(H(view, 1, 'Application for Financial Aid')) self.add_child(P(view, text='Name: %s' % funding_request.name)) self.add_child(P(view, text='Surname: %s' % funding_request.surname)) self.add_child( P(view, text='Email: %s' % funding_request.email_address)) self.add_child( P(view, text='Current status: %s.' % funding_request.grant_status)) self.add_child(H(view, 2, 'Feedback from the financial aid team')) if funding_request.feedback_message: self.add_child(P(view, text=funding_request.feedback_message)) else: self.add_child( P(view, text= 'There is no feedback message for you from the organisers')) if funding_request.allow_user_changes: self.add_child( P(view, text='You can still edit/change your request')) self.add_child( Nav(view).with_bookmarks( [apply_bookmark.with_description('Edit application')]))
def __init__(self, view, main_bookmarks): super().__init__(view) self.use_layout(PageLayout(document_layout=Container())) contents_layout = ColumnLayout(ColumnOptions('main', ResponsiveSize(lg=6))).with_slots() self.layout.contents.use_layout(contents_layout) menu = Nav(view).use_layout(TabLayout()).with_bookmarks(main_bookmarks) self.layout.header.add_child(menu)
def __init__(self, view, nav_layout=None): super(TabbedPanel, self).__init__(view) self.tabs = [] self.nav = self.add_child( Nav(view).use_layout(nav_layout or TabLayout())) self.content_panel = self.add_child(Div(view)) self.content_panel.append_class('tab-content')
def __init__(self, view, main_bookmarks): super(MenuPage, self).__init__(view) self.use_layout(PageLayout(document_layout=Container())) contents_layout = ColumnLayout( ('main', ResponsiveSize(md=4))).with_slots() self.layout.contents.use_layout(contents_layout) self.layout.header.add_child( Nav(view).use_layout(TabLayout()).with_bookmarks(main_bookmarks))
def __init__(self, view, bookmarks): super(MyCustomPage, self).__init__(view) self.use_layout(PageLayout(document_layout=Container())) contents_layout = ColumnLayout(ColumnOptions('secondary', size=ResponsiveSize(md=3)), ColumnOptions('main', size=ResponsiveSize(md=9))).with_slots() self.layout.contents.use_layout(contents_layout) menu = Nav(view).use_layout(TabLayout()).with_bookmarks(bookmarks) self.layout.header.add_child(menu)
def __init__(self, view): super(I18nExample, self).__init__(view) menu = Nav(self.view).use_layout(PillLayout()).with_languages() self.add_child(menu) current_url = Url.get_current_url() message = _('This is a translated message. The current URL is "%s".' ) % current_url.path self.add_child(P(view, text=message))
def __init__(self, view): super(HomePage, self).__init__(view) menu = Nav(self.view).use_layout( PillLayout(stacked=True)).with_languages() self.body.add_child(menu) current_url = Url.get_current_url() message = _('This is a translated string. The current URL is "%s".') \ % current_url.path self.body.add_child(P(view, text=message))
def __init__(self, view): super(HomePanel, self).__init__(view) panel = RefreshedPanel(view, 'my_refreshedpanel') bookmarks = [panel.get_bookmark(1), panel.get_bookmark(2), panel.get_bookmark(3)] self.add_child(H(view, 1, text='Refreshing widget')) self.add_child(Nav(view).use_layout(TabLayout()).with_bookmarks(bookmarks)) self.add_child(panel)
def __init__(self, view, bookmarks): super(AddressBookPage, self).__init__(view) self.body.use_layout(Container()) layout = ResponsiveLayout('md', colour_theme='dark', bg_scheme='primary') navbar = Navbar(view, css_id='my_nav').use_layout(layout) navbar.layout.set_brand_text('Address book') navbar.layout.add(Nav(view).with_bookmarks(bookmarks)) self.body.add_child(navbar)
def __init__(self, view, bookmarks): super().__init__(view) self.use_layout(PageLayout(document_layout=Container())) contents_layout = ColumnLayout(ColumnOptions('main', size=ResponsiveSize())).with_slots() self.layout.contents.use_layout(contents_layout) layout = ResponsiveLayout('md', colour_theme='dark', bg_scheme='primary') navbar = Navbar(view, css_id='my_nav').use_layout(layout) navbar.layout.set_brand_text('Address book') navbar.layout.add(Nav(view).with_bookmarks(bookmarks)) self.layout.header.add_child(navbar)
def test_populating(web_fixture): """Navs can be populated with a list of A's or Bookmarks.""" # Case: a normal menu from bookmarks item_specs = [Bookmark('/', '/href1', 'description1'), Bookmark('/', '/go_to_href', 'description2')] menu = Nav(web_fixture.view).with_bookmarks(item_specs) tester = WidgetTester(menu) [item1, item2] = menu.menu_items assert item1.a.href.path == '/href1' assert item1.a.children[0].value == 'description1' assert item2.a.href.path == '/go_to_href' assert item2.a.children[0].value == 'description2' #case: using A's a_list = [A.from_bookmark(web_fixture.view, i) for i in item_specs] menu = Nav(web_fixture.view).with_a_list(a_list) [item1, item2] = menu.menu_items assert item1.a is a_list[0] assert item2.a is a_list[1]
def __init__(self, view, home_bookmark): super(AddressAppPage, self).__init__(view) self.use_layout(PageLayout(document_layout=Container())) contents_layout = ColumnLayout(('main', ResponsiveSize(lg=6))).with_slots() self.layout.contents.use_layout(contents_layout) login_session = LoginSession.for_current_session() if login_session.is_logged_in(): logged_in_as = login_session.account.email else: logged_in_as = 'Not logged in' self.layout.header.add_child(P(view, text=logged_in_as)) self.layout.header.add_child(Nav(view).use_layout(TabLayout()).with_bookmarks([home_bookmark]))
def __init__(self, view, accounts): super(LoginFirst, self).__init__(view) self.use_layout(Container()) self.accounts = accounts self.add_child( P(view, text= 'You are not logged in. Please log into your account to apply for, or check the status of your financial aid.' )) self.add_child( Nav(view).with_bookmarks([ accounts.get_bookmark(relative_path='/login'), accounts.get_bookmark(relative_path='/register') ]))
def test_visual_feedback_on_items(web_fixture, visual_feedback_scenarios): """The state of a MenuItem is visually indicated to a user.""" menu = Nav(web_fixture.view) menu.add_a(A(web_fixture.view, Url('/an_url'))) menu.add_a(visual_feedback_scenarios.menu_item_with_state) [defaulted_item, item_with_state] = menu.html_representation.children [defaulted_a] = defaulted_item.children [a_with_state] = item_with_state.children assert visual_feedback_scenarios.state_indicator_class not in defaulted_a.get_attribute('class') assert visual_feedback_scenarios.state_indicator_class in a_with_state.get_attribute('class')
def __init__(self, view, bookmarks): super(FundingRequestPage, self).__init__(view) self.head.add_css(Url('/css/pyconza2019.css')) self.use_layout(PageLayout(document_layout=Container())) contents_layout = ColumnLayout( ColumnOptions('main', size=ResponsiveSize())).with_slots() self.layout.contents.use_layout(contents_layout) layout = ResponsiveLayout('md', colour_theme='dark', bg_scheme='primary') navbar = Navbar(view, css_id='my_nav').use_layout(layout) navbar.layout.set_brand_text('PyConZA 2019 Financial Aid') navbar.layout.add(Nav(view).with_bookmarks(bookmarks)) if LoginSession.for_current_session().is_logged_in(): navbar.layout.add(LogoutForm(view)) self.layout.header.add_child(navbar)
def navs(fixture): """A Nav is a menu with css classes for styling by Bootstrap.""" bookmarks = [Bookmark('', '/one', 'One'), Bookmark('', '/two', 'Two')] menu = Nav(fixture.view).with_bookmarks(bookmarks) # A nav is an ul.nav vassert(menu.html_representation.tag_name == 'ul') vassert('nav' in menu.html_representation.get_attribute('class')) # Containing a li for each menu item [one, two] = menu.html_representation.children for item, expected_href, expected_description in [(one, '/one', 'One'), (two, '/two', 'Two')]: vassert(item.tag_name == 'li') vassert(item.get_attribute('class') == 'nav-item') [a] = item.children vassert(a.get_attribute('href') == expected_href) vassert(a.children[0].value == expected_description) vassert(a.get_attribute('class') == 'nav-link')
def __init__(self, view, apply_bookmark): super(MyFundingRequestStatus, self).__init__(view) if not CurrentUserSession().is_logged_in_as_super_user(): funding_requests = FundingRequest.find_requests( account=CurrentUserSession().account) if len(funding_requests) == 1: funding_request = funding_requests[0] self.add_child( FundingRequestSummary(view, funding_request, apply_bookmark)) else: self.add_child( P(view, text='You have not applied for financial aid yet.')) self.add_child( Nav(view).with_bookmarks( [apply_bookmark.with_description('Apply here!')])) self.add_child( P(view, text= 'Once you have applied, please check back here to see the status of your application.' ))
def new_nav(self): return Nav(self.web_fixture.view).with_bookmarks(self.bookmarks)