예제 #1
0
def test_page_url_conflict():
    page_one = Page('one', core.Container())
    page_two = Page('two', core.Container(), url='/one')

    app = Dazzler(__name__)
    with pytest.raises(PageConflictError) as context:
        app.add_page(page_one, page_two)

    assert context.value.args[0] == 'Duplicate page url: two@/one'
예제 #2
0
async def test_page_meta_attributes(start_page, browser):
    meta = [
        {
            'name': 'description',
            'content': 'test dazzler'
        },
        {
            'name': 'custom',
            'content': 'customized'
        },
    ]
    await start_page(
        Page(name='meta',
             layout=core.Container('Hello', identity='layout'),
             meta_tags=meta))
    await asyncio.sleep(0.001)
    meta_tags = await browser.wait_for_elements_by_css_selector('meta')

    # Meta charset + http-equiv always present (+2)
    assert len(meta_tags) == 4

    for i in range(2, len(meta_tags)):
        meta_dict = meta[i - 2]
        meta_tag = meta_tags[i]
        for k, v in meta_dict.items():
            assert meta_tag.get_attribute(k) == v
예제 #3
0
async def test_package_route(start_page, browser):
    async def package_route(_):
        return web.Response(body='<html><head></head><body>'
                            '<div id="content">Package route</div>'
                            '</body></html>',
                            content_type='text/html')

    await start_page(
        Page('package',
             core.Container(),
             routes=[Route('/package-route', package_route)]))

    await browser.get('http://localhost:8150/package-route')
    await browser.wait_for_text_to_equal('#content', 'Package route')
예제 #4
0
async def test_html_single(start_page, browser, tag_name, attributes):
    # Test attributes are set and render.
    page = Page(__name__,
                core.Html(tag_name, attributes=attributes, identity='html'))
    await start_page(page)

    component = await browser.wait_for_element_by_id('html')

    for k, v in attributes.items():
        if k == 'children':
            await browser.wait_for_text_to_equal('#html', v)
        else:
            attr = component.get_attribute(k)
            assert attr == str(v)
예제 #5
0
async def test_page_routes(start_page, browser):

    page = Page('page-routes', core.Container())

    # pylint: disable=unused-variable
    @page.route('/page-route')
    async def page_route(_):
        return web.Response(body='<html><head></head><body>'
                            '<div id="content">Page route</div>'
                            '</body></html>',
                            content_type='text/html')

    await start_page(page)

    await browser.get('http://localhost:8150/page-routes/page-route')
    await browser.wait_for_text_to_equal('#content', 'Page route')
예제 #6
0
async def test_page_requirements_package_override(start_page, browser):
    # Overriding the package is an optimization if some pages uses big bundles
    # and others pages are more lightweight, down the line maybe add
    # on-demand loading of requirements, it's already set up for it.
    # noinspection PyUnresolvedReferences
    from tests.components import spec_components as spec  # noqa: F401

    page = Page(__name__,
                core.Container('Rendered'),
                packages=['dazzler_core'])
    await start_page(page)
    await browser.wait_for_element_by_css_selector('.dazzler-rendered')

    scripts = await browser.wait_for_elements_by_css_selector('script')
    for script in scripts:
        src = script.get_attribute('src')
        assert 'dazzler_test' not in src
예제 #7
0
async def test_middleware(start_visit, browser):
    page = Page(__name__, layout=layout, url='/')

    @page.bind(Trigger('cookie-setter', 'clicks'))
    async def on_cookie(ctx: BindingContext):
        cookie = ctx.request.cookies.get('dummy')
        await ctx.set_aspect('cookie-output', children=cookie)

    app = Dazzler(__name__)
    app.middlewares.append(DummyMiddleware())
    app.add_page(page)

    await start_visit(app)

    await browser.wait_for_text_to_equal('#request-output', 'dummy')
    await browser.click('#cookie-setter')
    await browser.wait_for_text_to_equal('#cookie-output', 'dummy-cookie')
예제 #8
0
def session_app():
    app = Dazzler(__name__)
    app.config.session.duration = 3
    app.config.secret_key = uuid.uuid4().hex

    page = Page(__name__,
                core.Container(
                    [core.Container(identity='session-output', clicks=1)]),
                url='/')

    @page.bind(Trigger('session-output', 'clicks'))
    async def on_session(ctx: BindingContext):
        await ctx.set_aspect('session-output', children=ctx.session.session_id)

    app.add_page(page)

    return app
예제 #9
0
async def test_auth_from_configs(start_visit, browser):
    app = Dazzler(__name__)
    app.config.authentication.enable = True
    app.config.session.backend = 'Redis'
    app.config.authentication.authenticator = \
        'tests.test_dazzler_auth:DummyAuthenticator'

    page = Page(__name__,
                core.Container('my-page', identity='content'),
                require_login=True,
                url='/')
    app.add_page(page)

    await start_visit(app)
    await browser.get('http://localhost:8150/')

    await proceed_login(browser, 'AgentSmith', 'SuperSecret1')
    await browser.wait_for_text_to_equal('#content', 'my-page')
예제 #10
0
async def test_session(start_visit, browser, backend):
    app = Dazzler(__name__)
    app.config.session.enable = False
    app.config.session.duration = 3
    app.middlewares.append(SessionMiddleware(app, backend=backend(app)))

    page = Page(__name__,
                url='/',
                layout=core.Container([
                    core.Button('Click', identity='session-click'),
                    core.Container(identity='session-output'),
                    core.Button('Remove session', identity='remove-session'),
                ]))

    @page.bind(Trigger('session-click', 'clicks'))
    async def on_session(ctx: BindingContext):
        session = ctx.request['session']

        clicks = await session.get('clicks') or 0
        clicks += 1
        await session.set('clicks', clicks)

        await ctx.set_aspect('session-output', children=f'Clicked {clicks}')

    @page.bind(Trigger('remove-session', 'clicks'))
    async def on_remove(ctx: BindingContext):
        session = ctx.request['session']
        await session.delete('clicks')

    app.add_page(page)

    await start_visit(app)

    for i in range(1, 4):
        await browser.get('http://localhost:8150/')
        await browser.click('#session-click')
        await browser.wait_for_text_to_equal('#session-output', f'Clicked {i}')

    # Delete session item
    await browser.click('#remove-session')
    await browser.click('#session-click')
    await browser.wait_for_text_to_equal('#session-output', 'Clicked 1')
예제 #11
0
def auth_app():
    app = Dazzler(__name__)
    page = Page('test-auth',
                core.Container([
                    core.Html('h2', 'logged-in', identity='header'),
                    core.Container(identity='username-output'),
                    _auth.Logout('/auth/logout', identity='logout')
                ]),
                url='/',
                require_login=True)

    @page.bind(Trigger('header', 'children'))
    async def on_username(ctx):
        user = ctx.request['user']
        await ctx.set_aspect('username-output', children=user.username)

    app.add_page(page)
    app.config.session.backend = 'Redis'

    DazzlerAuth(app, DummyAuthenticator())

    return app
예제 #12
0
"""
Page same_identity of dazzler
Created 2019-06-17
"""
from dazzler.components import core
from dazzler.system import Page, Trigger, BindingContext, State

page = Page(
    __name__,
    core.Container([
        core.Container(
            core.Input(value=0, type='number', identity='same'),
            identity='container'
        ),
        core.Button('click', identity='click')
    ])
)


@page.bind(Trigger('click', 'clicks'), State('container', 'children'))
async def on_click(ctx: BindingContext):
    component = ctx.states['container']['children']
    component.value = ctx.trigger.value
    await ctx.set_aspect(
        'container',
        children=component
    )
예제 #13
0
from dazzler.components import core, extra
from dazzler.system import Page, BindingContext

page = Page(
    __name__,
    core.Container([
        extra.TreeView([
            'item12', {
                'identifier':
                'nest',
                'label':
                'nest',
                'items': [
                    'nested1', 'nested2', {
                        'label': 'subnest',
                        'identifier': 'subnest',
                        'items': ['sub1', 'sub2']
                    }
                ],
            }
        ],
                       identity='treeview'),
        core.Container(identity='output')
    ]))


@page.bind('selected@treeview')
async def on_selected(ctx: BindingContext):
    await ctx.set_aspect('output', children=ctx.trigger.value)
예제 #14
0
            [1, 2, 3, 4],
            [1, 'foo', 'bar', 4],
            [{'arr': [1, 2, 3], 'foo': 'bar'}],
            [[1, 2, 4],  ['foo', 'bar']]
        ]
    )
] for i in range(0, 4)), 2)))

page = Page(
    __name__,
    core.Container([
        core.Store(identity='empty-store'),
        core.Store(data={'foo': 'bar'}, identity='initial-store'),
        core.Button('click', identity='click'),
        core.Container(identity='click-output'),
        core.Container(identity='initial-output'),
        core.Button('type-click', identity='type-click'),
        core.Store(identity='type-store'),
        core.Container(identity='type-output'),
        core.Button('get-aspect', identity='get-aspect-click'),
        core.Container(identity='get-aspect-output')
    ])
)


@page.bind(Trigger('initial-store', 'data'))
async def initial(ctx: BindingContext):
    await ctx.set_aspect(
        'initial-output',
        children=json.dumps(ctx.trigger.value)
    )
예제 #15
0
from dazzler import Dazzler
from dazzler.system import Page

from dazzler.components import core

app = Dazzler(__name__)
app.config.requirements.prefer_external = True

app.add_page(Page('index', core.Container('foo'), url='/'))
예제 #16
0
import asyncio
import json
from dazzler.components import core
from dazzler.system import Page, Trigger, BindingContext, State

page = Page(
    'binding-tree',
    core.Container([
        core.Button('trigger', identity='trigger'),
        core.Container([
            core.Container([
                core.Input(identity=f'output-{i}', type='number')
                for i in range(1, 3)
            ]),
            core.Container([
                core.Input(identity=f'value-{i}', type='number')
                for i in range(1, 11)
            ]),
            core.Container('[]', identity='output'),
            core.Container(identity='done')
        ])
    ]))


@page.bind(Trigger('trigger', 'clicks'))
async def trigger_click(context: BindingContext):
    await context.set_aspect('output-1', value=1)
    # Got to alternate the inputs for the first set to complete and let
    # frontend to register the state and all,
    # so as long as this start after and the other delay
    # is a little higher it should be ok.
예제 #17
0
"""
Page get_aspect_error of dazzler
Created 2019-06-15
"""
from dazzler.components import core
from dazzler.system import Page, Trigger, BindingContext
from dazzler.errors import GetAspectError

page = Page(
    __name__,
    core.Container([
        core.Button('click error', identity='click-error'),
        core.Container(identity='error-output')
    ]))


@page.bind(Trigger('click-error', 'clicks'))
async def trigger_error(ctx: BindingContext):
    try:
        await ctx.get_aspect('invalid', 'error')
    except GetAspectError as err:
        await ctx.set_aspect('error-output', children=err.args[0])
예제 #18
0
from dazzler import Dazzler
from dazzler.components import core
from dazzler.system import Page

app = Dazzler(__name__)


async def layout(_):
    return core.Container('Layout as function', identity='layout')


page = Page(
    __name__,
    url='/',
    layout=layout,
)
app.add_page(page)

if __name__ == '__main__':
    app.start('-v --debug=1 --port=5420'.split())
예제 #19
0
파일: icons.py 프로젝트: jbampton/dazzler
"""
Page icons of dazzler
Created 2021-06-13
"""
from dazzler.components import core, icons
from dazzler.system import Page

page = Page(
    __name__,
    core.Container([
        icons.IconLoader([]),
        icons.LinearIconPack(),
        icons.FoundIconPack(),
        icons.OpenIconicPack(),
        icons.TypiconsPack(),
        core.Container(icons.Icon('lnr-home'), ),
        core.Container(icons.Icon('fi-home')),
        core.Container(icons.Icon('oi-bug')),
        core.Container(icons.Icon('typcn-globe')),
    ]))
예제 #20
0
from dazzler import Dazzler
from dazzler.components import core
from dazzler.system import Page, Trigger, BindingContext

page = Page(name='page',
            url='/',
            layout=core.Container([
                core.Button('click', identity='clicker'),
                core.Container('output', identity='output')
            ]))

app = Dazzler(__name__)
app.add_page(page)


@page.bind(Trigger('clicker', 'clicks'))
async def on_click(context: BindingContext):
    await context.set_aspect('output',
                             children=core.Container('from binding',
                                                     id='from-binding'))


if __name__ == '__main__':
    app.start('-v --debug=1 --port=8151'.split())
예제 #21
0
from dazzler import Dazzler
from dazzler.components import core
from dazzler.system import Page

app = Dazzler(__name__)

for num in ('one', 'two', 'three', 'four'):
    page = Page(
        name=num,
        layout=core.Container(f'Page {num}', identity='content'),
        title=f'Page {num}',
    )

    app.add_page(page)


if __name__ == '__main__':
    app.start('-v --debug 1'.split())
예제 #22
0
파일: pager.py 프로젝트: jbampton/dazzler
"""
Page pager of dazzler
Created 2019-09-03
"""
from dazzler.components import core, extra
from dazzler.system import Page, Trigger, BindingContext

items = list(range(1, 200))

page = Page(
    __name__,
    core.Container([
        core.Grid([], columns=2, identity='output'),
        extra.Pager(total_items=len(items),
                    items_per_page=10,
                    identity='pager'),
        core.Container(identity='num_pages'),
    ]))


@page.bind(Trigger('pager', 'current_page'))
async def on_page(ctx: BindingContext):
    start = await ctx.get_aspect('pager', 'start_offset')
    stop = await ctx.get_aspect('pager', 'end_offset')
    await ctx.set_aspect('output', children=items[start:stop])


@page.bind(Trigger('pager', 'total_pages'))
async def on_total(ctx: BindingContext):
    await ctx.set_aspect('num_pages', children=ctx.trigger.value)
예제 #23
0
"""
Page initial_trigger of dazzler
Created 2019-06-15
"""
from dazzler.components import core
from dazzler.system import Page, Trigger, BindingContext, State

page = Page(
    'initial-trigger',
    core.Container([
        core.Input(value=10, identity='input'),
        core.Container(identity='output'),
        core.Input(value=88, identity='state'),
        core.Container(identity='state-output')
    ]))


@page.bind(Trigger('input', 'value'), State('state', 'value'))
async def on_value(context: BindingContext):
    await context.set_aspect('output',
                             children=f'Input {context.trigger.value}')
    await context.set_aspect(
        'state-output', children=F'State {context.states["state"]["value"]}')
예제 #24
0
Created 2019-08-24
"""
import datetime
import pytz

from dazzler.components import core, calendar
from dazzler.system import Page

past = datetime.datetime(day=22, month=11, year=1986, tzinfo=pytz.utc)
future = datetime.datetime(day=11, month=9, year=2031, tzinfo=pytz.utc)

page = Page(
    __name__,
    core.Container([
        calendar.Calendar(identity='initial-calendar'),
        # FIXME * 1000 JavaScript are in ms where Python ts in seconds.
        calendar.Calendar(
            datetime.datetime.timestamp(past) * 1000,
            identity='past-calendar'
        ),
        calendar.Calendar(
            datetime.datetime.timestamp(future) * 1000,
            identity='future-calendar'
        ),
        calendar.Calendar(use_selected=False),
        calendar.DatePicker(identity='single-picker'),
        calendar.TimePicker(fallback_mode=True, identity='time-picker'),
        calendar.Timestamp(past.timestamp() * 1000, format='DD MM YYYY'),
    ])
)
예제 #25
0
"""
Page progress of dazzler
Created 2019-06-26
"""
from dazzler.components import core
from dazzler.system import Page, Trigger, BindingContext, State

page = Page(
    __name__,
    core.Container([
        core.ProgressBar(identity='progress',
                         minimum=0,
                         high=80,
                         low=20,
                         maximum=100,
                         rounded=True,
                         optimum=21,
                         striped=True,
                         progress_text='percent'),
        core.Button('add progress', identity='progress-btn'),
        core.Container(identity='counter')
    ]))


@page.bind(Trigger('progress-btn', 'clicks'), State('progress', 'value'))
async def on_meter(ctx: BindingContext):
    new_value = (ctx.states['progress']['value'] or 0) + 1
    await ctx.set_aspect('progress', value=new_value)
    await ctx.set_aspect('counter', children=new_value)
예제 #26
0
page = Page(
    __name__,
    core.Container([
        spec.ComponentAsAspect(
            identity='component',
            single=core.Button('single', identity='single'),
            array=[
                core.Input(value=x, identity=f'array-{x}', type='number')
                for x in arr
            ],
            shape={'shaped': core.Button('shaped', identity='shaped')},
            list_of_dict=[
                {
                    'label': core.Container(
                        f'label{x}', identity=f'label-{x}'
                    ),
                    'value': f'label-{x}'
                } for x in arr
            ]
        ),
        core.Container(identity='single-output'),
        core.Container([
            core.Container(identity=f'output-array-{x}') for x in arr
        ]),
        core.Button('click sum', identity='click-sum'),
        core.Container(identity='sum-output'),
        core.Container(identity='shaped-output'),
    ])
)
예제 #27
0
"""
Page markdown of dazzler
Created 2019-08-19
"""
from dazzler.components import core, markdown as md
from dazzler.system import Page

text = '''
# Foo
## Bar
[google](http://google.com)

```jsx
const Foo = props => <div>{props.text}</div>;
```
'''

page = Page(
    __name__,
    core.Container([
        md.Markdown(text, identity='markdown'),
        md.CodeBlock(value=text, language='md')
    ]))
예제 #28
0
"""
Page grid of dazzler
Created 2019-07-08
"""
from dazzler.components import core
from dazzler.system import Page

page = Page(
    __name__,
    core.Container(
        [core.Grid([x for x in range(1, 101)], 10, identity='grid')]))
예제 #29
0
import functools

from dazzler.components import core
from dazzler.system import Page, Trigger, BindingContext

page = Page(
    'binding-chain',
    core.Container([
        core.Button(x, identity=f'trigger-{x}') for x in range(1, 21)
    ] + [core.Container(identity='output')])
)


async def update_next(context: BindingContext, num: int = 0):
    await context.set_aspect(
        f'trigger-{num+1}',
        clicks=1,
    )


@page.bind(Trigger('trigger-20', 'clicks'))
async def last_trigger(context: BindingContext):
    await context.set_aspect('output', children='output generated')


for i in range(1, 20):
    page.bind(Trigger(f'trigger-{i}', 'clicks'))(
        functools.partial(update_next, num=i)
    )
예제 #30
0
파일: form.py 프로젝트: jbampton/dazzler
"""
Page form of dazzler
Created 2019-07-14
"""
from aiohttp import web

from dazzler.components import core
from dazzler.system import Page, RouteMethod

page = Page(
    __name__,
    core.Container([
        core.Form(fields=[
            {
                'label': 'Field 1',
                'name': 'field1',
                'type': 'text'
            },
        ],
                  action='/submit-form',
                  method='post',
                  identity='form')
    ]))


@page.route('/submit-form', method=RouteMethod.POST, prefix=False)
async def submit(request: web.Request):
    data = await request.post()
    return web.Response(body=f'<div id="output">{data.get("field1")}</div>',
                        content_type='text/html')