123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769 |
- import asyncio
- import json
- import os
- import re
- import threading
- import time
- from functools import partial
- from os import path
- from percy import percySnapshot
- from selenium.webdriver import Chrome
- from selenium.webdriver.support.ui import Select
- from pywebio.input import *
- from pywebio.output import *
- from pywebio.session import *
- here_dir = path.dirname(path.abspath(__file__))
- def get_visible_form(browser):
- forms = browser.find_elements_by_css_selector('#input-cards > div')
- for f in forms:
- if f.is_displayed():
- return f
- def basic_output():
- set_env(title="PyWebIO Test")
- set_scope('top')
- put_markdown('### Basic')
- for i in range(3):
- put_text('text_%s' % i)
- put_text('测试空格:20空格:[%s]结束' % (' ' * 20))
- for i in range(3):
- put_text('inline_text_%s' % i, inline=True)
- put_markdown("""### put_markdown 测试
- `行内代码`
- 无序列表:
- - 北京
- - 上海
- - 天津
- 有序列表:
- 1. 北京
- 2. 上海
- 3. 天津
- [链接](./#)
- ~~删除线~~
- """)
- put_link('链接', '#')
- put_text('<hr/>:')
- put_html("<hr/>")
- put_markdown('### Style')
- put_text('Red').style('color:red')
- put_text('Red').style('color:red')
- put_markdown('~~del~~').style('color:red')
- put_table([
- ['A', 'B'],
- ['C', put_text('Red').style('color:red')],
- ])
- put_collapse('title', [
- put_text('text').style('margin-left:20px'),
- put_markdown('~~del~~').style('margin-left:20px'),
- ], open=True)
- put_markdown('### Table')
- put_table([
- ['Name', 'Gender', 'Address'],
- ['Wang', 'M', 'China'],
- ['Liu', 'W', 'America'],
- ])
- put_table([
- ['Wang', 'M', 'China'],
- ['Liu', 'W', 'America'],
- ], header=['Name', 'Gender', 'Address'])
- put_table([
- {"Course": "OS", "Score": "80"},
- {"Course": "DB", "Score": "93"},
- ], header=["Course", "Score"])
- put_table([
- {"Course": "OS", "Score": "80"},
- {"Course": "DB", "Score": "93"},
- ], header=[("课程", "Course"), ("得分", "Score")])
- img_data = open(path.join(here_dir, 'assets', 'img.png'), 'rb').read()
- put_table([
- ['Type', 'Content'],
- ['text', '<hr/>'],
- ['html', put_html('X<sup>2</sup>')],
- ['buttons', put_buttons(['A', 'B'], onclick=put_text, small=True)],
- ['markdown', put_markdown('`awesome PyWebIO!`\n - 1\n - 2\n - 3')],
- ['file', put_file('hello.text', b'')],
- ['image', put_image(img_data)],
- ['table', put_table([
- ['A', 'B'],
- [put_markdown('`C`'), put_markdown('`D`')]
- ])]
- ])
- put_markdown('### Code')
- with use_scope('scroll_basis'):
- put_code(json.dumps(dict(name='pywebio', author='wangweimin'), indent=4), 'json')
- put_text('move ⬆ code block to screen ... :')
- with use_scope('scroll_basis_btns'):
- put_buttons(buttons=[
- ('BOTTOM', Position.BOTTOM),
- ('TOP', Position.TOP),
- ('MIDDLE', Position.MIDDLE),
- ], onclick=lambda pos: scroll_to('scroll_basis', pos))
- def show_popup():
- popup('Popup title', [
- put_html('<h3>Popup Content</h3>'),
- 'html: <br/>',
- put_table([
- ['Type', 'Content'],
- ['html', put_html('X<sup>2</sup>')],
- ['text', '<hr/>'],
- ['buttons', put_buttons(['A', 'B'], onclick=put_text)],
- ['markdown', put_markdown('`Awesome PyWebIO!`')],
- ['file', put_file('hello.text', b'')],
- ['table', put_table([['A', 'B'], ['C', 'D']])]
- ]),
- put_buttons(['close_popup()'], onclick=lambda _: close_popup())
- ], size=PopupSize.NORMAL)
- with use_scope('popup_btn'):
- put_buttons([('popup()', '')], onclick=[show_popup])
- def edit_row(choice, row):
- put_text("You click %s button at row %s" % (choice, row), scope='table_cell_buttons')
- with use_scope('table_cell_buttons'):
- put_table([
- ['Idx', 'Actions'],
- ['1', put_buttons(['edit', 'delete'], onclick=partial(edit_row, row=1))],
- ['2', put_buttons(['edit', 'delete'], onclick=partial(edit_row, row=2))],
- ['3', put_buttons(['edit', 'delete'], onclick=partial(edit_row, row=3))],
- ])
- with use_scope('put_buttons'):
- put_buttons(['A', 'B', 'C'], onclick=partial(put_text, scope='put_buttons'))
- # put_button
- put_button("click me", onclick=lambda: toast("Clicked"), color='success', outline=True)
- put_markdown('### Image')
- put_image(img_data)
- from PIL.Image import open as pil_open
- pil_img = pil_open(path.join(here_dir, 'assets', 'img.png'))
- put_image(pil_img, width="30px")
- put_image('https://cdn.jsdelivr.net/gh/wang0618/pywebio/test/assets/img.png', height="50px")
- put_file('hello_word.txt', b'hello word!')
- put_collapse('Collapse', [
- 'text',
- put_markdown('~~删除线~~'),
- put_table([
- ['商品', '价格'],
- ['苹果', '5.5'],
- ['香蕉', '7'],
- ])
- ], open=True)
- put_collapse('title', 'something', open=True)
- put_scrollable('scrollable\n' * 20, height=50, keep_bottom=True)
- put_markdown('### Scope')
- with use_scope('scope1'):
- put_text("to be cleared")
- clear()
- put_text('A') # 输出内容: A
- put_text('B', position=0) # 输出内容: B A
- put_text('C', position=-2) # 输出内容: B C A
- with use_scope('scope2'):
- put_text('scope2')
- put_text('scope2')
- put_text('D', position=1) # 输出内容: B D C A
- put_text('before=top again', scope='top')
- with use_scope('to_remove'):
- put_text('to remove')
- remove('to_remove')
- put_markdown('### Info')
- from pywebio import session
- session_info = session.info
- from django.http import HttpRequest
- from flask import Request
- from tornado.httputil import HTTPServerRequest
- from aiohttp.web import BaseRequest
- from starlette.websockets import WebSocket
- request_type = {
- 'tornado': HTTPServerRequest,
- 'flask': Request,
- 'django': HttpRequest,
- 'aiohttp': BaseRequest,
- 'starlette': WebSocket,
- }
- request_ok = isinstance(session_info.request, request_type.get(session_info.backend))
- if not request_ok:
- print('Error: request check error: backend %s, request type %s, class %s' %
- (session_info.backend, type(session_info.request).__name__, session_info.request))
- put_markdown(rf"""### 会话信息
- ```
- * `user_agent`:
- * `is_mobile` (bool): {session_info.user_agent.is_mobile}
- * `is_tablet` (bool): {session_info.user_agent.is_tablet}
- * `is_pc` (bool): {session_info.user_agent.is_pc}
- * `is_touch_capable` (bool): {session_info.user_agent.is_touch_capable}
- * `browser.family` (str): {session_info.user_agent.browser.family}
- * `os.family` (str): {session_info.user_agent.os.family}
- * `os.version` (tuple): {session_info.user_agent.os.version}
- * `os.version_string` (str): {session_info.user_agent.os.version_string}
- * `device.family` (str): {session_info.user_agent.device.family}
- * `device.brand` (str): {session_info.user_agent.device.brand}
- * `device.model` (str): {session_info.user_agent.device.model}
- * `user_language` (str): {session_info.user_language}
- * `server_host` (str): {session_info.server_host}
- * `origin` (str): {session_info.origin or 'http://' + session_info.server_host}
- * `user_ip` (str): {session_info.user_ip}
- * `request type check` (str): {request_ok}
- ```
- """)
- put_markdown('### Layout')
- put_row([
- put_column([
- put_code('A'),
- put_row([
- put_code('B1'), None,
- put_code('B2'), None,
- put_code('B3'),
- ]),
- put_code('C'),
- ]), None,
- put_code('python'), None,
- put_code('python\n' * 20).style('max-height:200px;'),
- ])
- put_grid([
- [put_code('[%s,%s]' % (x, y)).style('margin-right:10px;') for y in range(4)]
- for x in range(5)
- ], direction='column')
- put_row([put_code(i).style('margin-right:10px;') for i in range(4)], 'repeat(auto-fill, 25%)')
- put_markdown('### Span')
- cell = lambda text: put_code(text).style('margin-right:10px;')
- put_grid([
- [span(cell('A'), col=2), None],
- [span(cell('C'), row=2, col=2), span(cell('D'), row=2)],
- [],
- ], cell_width='1fr', cell_height='1fr')
- put_table([
- ['C'],
- [span('E', col=2)],
- ], header=[span('A', row=2), 'B'])
- put_processbar('processbar', 0.3)
- set_processbar('processbar', 0.6)
- put_loading()
- # output
- hobby = output(put_text('Coding'))
- put_table([
- ['Name', 'Hobbies'],
- ['Wang', hobby]
- ])
- hobby.reset(put_text('Movie'))
- hobby.append(put_text('Music'), put_text('Drama'))
- hobby.insert(0, put_markdown('**Coding**'))
- put_table([
- ['Name', 'Hobbies'],
- ['Tom', put_scope('hobby', content=put_text('Coding'))]
- ])
- with use_scope('hobby', clear=True):
- put_text('Movie') # hobby is reset to Movie
- with use_scope('hobby'):
- put_text('Music')
- put_text('Drama')
- put_markdown('**Coding**', scope='hobby', position=0)
- def background_output():
- put_text("Background output")
- set_scope('background')
- def background():
- for i in range(20):
- put_text('%s ' % i, inline=True, scope='background')
- t = threading.Thread(target=background)
- register_thread(t)
- t.start()
- async def coro_background_output():
- put_text("Background output")
- set_scope('background')
- async def background():
- for i in range(20):
- put_text('%s ' % i, inline=True, scope='background')
- return run_async(background())
- def test_output(browser: Chrome, enable_percy=False, action_delay=0.5):
- """测试输出::
- run template.basic_output()
- template.background_output() # 或者 await template.coro_background_output()
- hold()
- """
- time.sleep(action_delay * 2) # 等待输出完毕
- # get focus
- browser.find_element_by_tag_name('body').click()
- time.sleep(action_delay * 2)
- browser.execute_script('$("html, body").scrollTop( $(document).height()+100);')
- time.sleep(action_delay)
- enable_percy and percySnapshot(browser, name='begin output')
- tab_btns = browser.find_elements_by_css_selector('#pywebio-scope-table_cell_buttons button')
- for btn in tab_btns:
- time.sleep(action_delay)
- browser.execute_script("arguments[0].click();", btn)
- btns = browser.find_elements_by_css_selector('#pywebio-scope-put_buttons button')
- for btn in btns:
- time.sleep(action_delay)
- browser.execute_script("arguments[0].click();", btn)
- # 滚动窗口
- btns = browser.find_elements_by_css_selector('#pywebio-scope-scroll_basis_btns button')
- for btn in btns:
- time.sleep(action_delay * 2)
- browser.execute_script("arguments[0].click();", btn)
- time.sleep(action_delay * 2)
- browser.execute_script('$("html, body").scrollTop( $(document).height()+100);')
- time.sleep(action_delay)
- enable_percy and percySnapshot(browser, name='basic output')
- # popup
- btn = browser.find_element_by_css_selector('#pywebio-scope-popup_btn button')
- browser.execute_script("arguments[0].click();", btn)
- time.sleep(action_delay * 2)
- enable_percy and percySnapshot(browser, name='popup')
- browser.execute_script("$('.modal').modal('hide');")
- def basic_input():
- js_res = yield eval_js('''(function(){
- for(var i=0;i<=limit;i++)
- a += i;
- return a;
- })()''', a=0, limit=100)
- assert js_res == 5050
- age = yield input("How old are you?", type=NUMBER)
- put_markdown(f'`{repr(age)}`')
- password = yield input("Input password", type=PASSWORD)
- put_markdown(f'`{repr(password)}`')
- # 下拉选择框
- gift = yield select('Which gift you want?', ['keyboard', 'ipad'])
- put_markdown(f'`{repr(gift)}`')
- # CheckBox
- agree = yield checkbox("用户协议", options=['I agree to terms and conditions'])
- put_markdown(f'`{repr(agree)}`')
- # Text Area
- text = yield textarea('Text Area', rows=3, placeholder='Some text')
- put_markdown(f'`{repr(text)}`')
- # 文件上传
- img = yield file_upload("Select a image:", accept="image/*", max_size=10 ** 7)
- put_image(img['content'], title=img['filename'])
- # 输入参数
- res = yield input('This is label', type=TEXT, placeholder='This is placeholder,required=True',
- help_text='This is help text', required=True)
- put_markdown(f'`{repr(res)}`')
- # 取消表单
- res = yield input_group('cancel test', [input(name='cancel')], cancelable=True)
- put_markdown(f'`{repr(res)}`')
- # 校验函数
- def check_age(p): # 检验函数校验通过时返回None,否则返回错误消息
- if p < 10:
- return 'Too young!!'
- if p > 60:
- return 'Too old!!'
- age = yield input("How old are you?", type=NUMBER, validate=check_age, help_text='age in [10, 60]')
- put_markdown(f'`{repr(age)}`')
- # Codemirror
- code = yield textarea('Code Edit', code={
- 'mode': "python", # 编辑区代码语言
- 'theme': 'darcula', # 编辑区darcula主题, Visit https://codemirror.net/demo/theme.html#cobalt to get more themes
- }, value='import something\n# Write your python code')
- put_markdown(f'`{repr(code)}`')
- # 输入组 cancelable
- info = yield input_group("Cancelable", [
- input('Input your name', name='name'),
- input('Input your age', name='age', type=NUMBER, validate=check_age, help_text='age in [10, 60]')
- ], cancelable=True)
- put_markdown(f'`{repr(info)}`')
- # input action
- def set_now_ts(set_value):
- set_value('set from action')
- val = yield input('Input action', action=('Set value', set_now_ts))
- assert val == 'set from action'
- def check_form(data): # 检验函数校验通过时返回None,否则返回 (input name,错误消息)
- if len(data['password']) > 6:
- return ('password', 'password太长!')
- check_item_data = []
- def check_item(data):
- check_item_data.append(repr(data))
- info = yield input_group('Input group', [
- input('Text', type=TEXT, datalist=['data-%s' % i for i in range(10)], name='text',
- required=True, help_text='required=True', validate=check_item),
- input('Number', type=NUMBER, value="42", name='number', validate=check_item),
- input('Float', type=FLOAT, name='float', validate=check_item),
- input('Password', type=PASSWORD, name='password', validate=check_item),
- textarea('Textarea', rows=3, maxlength=20, name='textarea',
- help_text='rows=3, maxlength=20', validate=check_item),
- textarea('Code', name='code', code={
- 'lineNumbers': False,
- 'indentUnit': 2,
- }, value='import something\n# Write your python code', validate=check_item),
- select('select-multiple', [
- {'label': '标签0,selected', 'value': '0', 'selected': True},
- {'label': '标签1,disabled', 'value': '1', 'disabled': True},
- ('标签2,selected', '2', True),
- ('标签3', '3'),
- ('标签4,disabled', '4', False, True),
- '标签5,selected',
- ], name='select-multiple', multiple=True, value=['标签5,selected'], required=True,
- help_text='required至少选择一项', validate=check_item),
- select('select', [
- {'label': '标签0', 'value': '0', 'selected': False},
- {'label': '标签1,disabled', 'value': '1', 'disabled': True},
- ('标签2', '2', False),
- ('标签3', '3'),
- ('标签4,disabled', '4', False, True),
- '标签5,selected',
- ], name='select', value=['标签5,selected'], validate=check_item),
- checkbox('checkbox-inline', [
- {'label': '标签0,selected', 'value': '0', 'selected': False},
- {'label': '标签1,disabled', 'value': '1', 'disabled': True},
- ('标签2,selected', '2', True),
- ('标签3', '3'),
- ('标签4,disabled', '4', False, True),
- '标签5,selected',
- ], inline=True, name='checkbox-inline', value=['标签5,selected', '标签0', '标签0,selected'], validate=check_item),
- checkbox('checkbox', [
- {'label': '标签0,selected', 'value': '0', 'selected': True},
- {'label': '标签1,disabled', 'value': '1', 'disabled': True},
- ('标签2,selected', '2', True),
- ('标签3', '3'),
- ('标签4,disabled', '4', False, True),
- '标签5',
- ], name='checkbox', validate=check_item),
- radio('radio-inline', [
- {'label': '标签0', 'value': '0', 'selected': False},
- {'label': '标签1,disabled', 'value': '1', 'disabled': True},
- ('标签2', '2', False),
- ('标签3', '3'),
- ('标签4,disabled', '4', False, True),
- '标签5,selected',
- ], inline=True, name='radio-inline', value='标签5,selected', validate=check_item),
- radio('radio', [
- {'label': '标签0', 'value': '0', 'selected': False},
- {'label': '标签1,disabled', 'value': '1', 'disabled': True},
- ('标签2', '2', False),
- ('标签3', '3'),
- ('标签4,disabled', '4', False, True),
- '标签5,selected',
- ], inline=False, name='radio', value='标签5,selected', validate=check_item),
- file_upload('file_upload', name='file_upload', max_size='10m'),
- actions('actions', [
- {'label': '提交', 'value': 'submit'},
- ('提交2', 'submit2'),
- '提交3',
- {'label': 'disabled', 'disabled': True},
- ('重置', 'reset', 'reset'),
- {'label': '取消', 'type': 'cancel'},
- ], name='actions', help_text='actions'),
- ], validate=check_form)
- put_text('`validate()` log:')
- put_code(json.dumps(sorted(list(set(check_item_data))), indent=4, ensure_ascii=False), 'json')
- put_text('Form result:')
- if info:
- put_code(json.dumps([repr(i) for i in sorted(info.items())], indent=4, ensure_ascii=False), 'json')
- # yield actions(['Continue'])
- def background_input():
- def background():
- time.sleep(1)
- res = input('background')
- put_markdown(f'`background: {repr(res)}`')
- t = threading.Thread(target=background)
- register_thread(t)
- t.start()
- res = input('front')
- put_markdown(f'`front: {repr(res)}`')
- async def coro_background_input():
- async def background():
- await asyncio.sleep(1)
- res = await input('background')
- put_markdown(f'`background: {repr(res)}`')
- run_async(background())
- res = await input('front')
- put_markdown(f'`front: {repr(res)}`')
- async def flask_coro_background_input():
- async def background():
- await run_asyncio_coroutine(asyncio.sleep(1))
- res = await input('background')
- put_markdown(f'`background: {repr(res)}`')
- run_async(background())
- res = await input('front')
- put_markdown(f'`front: {repr(res)}`')
- def test_input(browser: Chrome, enable_percy=False, action_delay=0.5):
- """测试输入::
- run template.basic_input()
- actions(['Continue'])
- template.background_input() # 或者 await template.coro_background_input() / flask_coro_background_input
- """
- browser.find_element_by_css_selector('#input-container input').send_keys("22")
- browser.find_element_by_tag_name('form').submit()
- time.sleep(action_delay)
- browser.find_element_by_css_selector('#input-container input').send_keys("secret")
- browser.find_element_by_tag_name('form').submit()
- time.sleep(action_delay)
- browser.find_element_by_tag_name('form').submit()
- # checkbox
- time.sleep(action_delay)
- browser.execute_script("arguments[0].click();", browser.find_element_by_css_selector('#input-container input'))
- browser.find_element_by_tag_name('form').submit()
- # Text Area
- time.sleep(action_delay)
- browser.find_element_by_css_selector('#input-container textarea').send_keys(" ".join(str(i) for i in range(20)))
- browser.find_element_by_tag_name('form').submit()
- # file
- time.sleep(action_delay)
- img_path = path.join(here_dir, 'assets', 'img.png')
- browser.find_element_by_css_selector('#input-container input').send_keys(img_path)
- browser.find_element_by_tag_name('form').submit()
- # text
- time.sleep(action_delay)
- browser.find_element_by_css_selector('#input-container input').send_keys("text")
- browser.find_element_by_tag_name('form').submit()
- # 表单取消
- time.sleep(action_delay)
- browser.execute_script("arguments[0].click();", browser.find_element_by_css_selector('.pywebio_cancel_btn'))
- # valid func, age in [10, 60]
- time.sleep(action_delay)
- browser.find_element_by_css_selector('#input-container input').send_keys("1")
- browser.find_element_by_tag_name('form').submit()
- time.sleep(action_delay)
- browser.find_element_by_css_selector('#input-container input').clear()
- browser.find_element_by_css_selector('#input-container input').send_keys("90")
- browser.find_element_by_tag_name('form').submit()
- time.sleep(action_delay)
- browser.find_element_by_css_selector('#input-container input').clear()
- browser.find_element_by_css_selector('#input-container input').send_keys("23")
- browser.find_element_by_tag_name('form').submit()
- # code
- time.sleep(action_delay)
- # browser.find_element_by_css_selector('textarea').send_keys(" ".join(str(i) for i in range(20)))
- browser.find_element_by_tag_name('form').submit()
- # Cancelable from group
- time.sleep(action_delay)
- browser.find_element_by_name('name').send_keys("name")
- time.sleep(action_delay * 2)
- browser.find_element_by_name('age').send_keys("90")
- browser.find_element_by_tag_name('form').submit()
- browser.execute_script('$("html, body").scrollTop( $(document).height()+100);')
- time.sleep(action_delay)
- enable_percy and percySnapshot(browser, name='input group invalid')
- time.sleep(action_delay)
- browser.find_element_by_name('age').clear()
- browser.find_element_by_name('age').send_keys("23")
- browser.find_element_by_tag_name('form').submit()
- # callback actions
- time.sleep(action_delay)
- browser.execute_script("arguments[0].click();", browser.find_element_by_css_selector('form button[type="button"]'))
- time.sleep(action_delay)
- # input action
- time.sleep(action_delay)
- browser.execute_script("arguments[0].click();", browser.find_element_by_css_selector('form button[type="button"]'))
- time.sleep(action_delay)
- browser.find_element_by_tag_name('form').submit()
- # Input group
- time.sleep(action_delay)
- browser.execute_script('$("html, body").scrollTop( $(document).height()+100);')
- time.sleep(action_delay)
- enable_percy and percySnapshot(browser, name='input group all')
- browser.find_element_by_name('text').send_keys("name")
- browser.find_element_by_name('number').send_keys("20")
- browser.find_element_by_name('float').send_keys("3.1415")
- browser.find_element_by_name('password').send_keys("password")
- browser.find_element_by_name('textarea').send_keys(" ".join(str(i) for i in range(20)))
- # browser.find_element_by_css_selector('[name="code"]').send_keys(" ".join(str(i) for i in range(10)))
- Select(browser.find_element_by_name('select-multiple')).select_by_index(0)
- # browser. find_element_by_css_selector('[name="select"]'). send_keys("name")
- # browser. find_element_by_css_selector('[name="checkbox-inline"]'). send_keys("name")
- # browser. find_element_by_css_selector('[name="checkbox"]'). send_keys("name")
- # browser. find_element_by_css_selector('[name="radio-inline"]'). send_keys("name")
- # browser. find_element_by_css_selector('[name="radio"]'). send_keys("name")
- browser.find_element_by_name('file_upload').send_keys(path.join(here_dir, 'assets', 'helloworld.txt'))
- browser.execute_script("$('form button').eq(1).click()")
- time.sleep(action_delay * 2)
- browser.execute_script('$("html, body").scrollTop( $(document).height()+100);')
- time.sleep(action_delay)
- enable_percy and percySnapshot(browser, name='input group all invalid')
- browser.find_element_by_name('password').clear()
- browser.find_element_by_name('password').send_keys("123")
- browser.execute_script("$('form button[type=\"submit\"]').eq(1).click()")
- time.sleep(action_delay * 2)
- browser.execute_script('$("html, body").scrollTop( $(document).height()+100);')
- time.sleep(action_delay * 2)
- enable_percy and percySnapshot(browser, name='input group all submit')
- browser.find_element_by_css_selector('form').submit()
- # background
- time.sleep(action_delay * 6)
- get_visible_form(browser).find_element_by_css_selector('#input-container input').send_keys("background")
- get_visible_form(browser).find_element_by_tag_name('form').submit()
- # front
- time.sleep(action_delay * 2)
- get_visible_form(browser).find_element_by_css_selector('#input-container input').send_keys("front")
- get_visible_form(browser).find_element_by_tag_name('form').submit()
- def set_defer_call():
- def deferred_1():
- open('test_defer.tmp', 'w').write('deferred_1')
- def deferred_2():
- open('test_defer.tmp', 'a').write('deferred_2')
- defer_call(deferred_1)
- defer_call(deferred_2)
- def test_defer_call():
- output = open('test_defer.tmp').read()
- assert "deferred_1" in output
- assert "deferred_2" in output
- os.remove('test_defer.tmp')
- def save_output(browser: Chrome, filename=None, process_func=None):
- """获取输出区html源码,并去除随机元素,供之后diff比较
- :param browser:
- :param filename: 保存文件名, 为 None 时,不保存为文件
- :param process_func: 自定义数据处理函数
- :return: 处理前后的html文本
- """
- raw_html = browser.find_element_by_id('markdown-body').get_attribute('innerHTML')
- html = re.sub(r'"pywebio-scope-.*?"', '', raw_html)
- html = re.sub(r'id="pywebio-.*?"', '', html)
- html = re.sub(r"\('pywebio-.*?'\)", '', html)
- html = re.sub(r"WebIO.pushData\(.*?\)", '', html)
- html = re.sub(r"</(.*?)>", r'</\g<1>>\n', html) # 进行断行方便后续的diff判断
- html = html.replace('"opacity: 1;"', '""').replace(' open=""', '') # so wired
- html = html.strip()
- if process_func:
- html = process_func(html)
- if filename:
- open(path.join(here_dir, 'output', filename), 'w').write(html)
- return raw_html, html
|