1
0
wangweimin 5 жил өмнө
parent
commit
7f1410e9bb

+ 22 - 0
.github/workflows/test.yml

@@ -0,0 +1,22 @@
+name: Tests
+on: [push, pull_request]
+jobs:
+  build:
+    runs-on: ubuntu-latest
+    steps:
+      - name: Checkout
+        uses: actions/checkout@master
+      - name: Set up Python 3.7
+        uses: actions/setup-python@v1
+        with:
+          python-version: 3.7
+      - name: Install JS deps
+        run: npm install -D @percy/agent
+      - name: Install Python deps
+        run: pip3 install -e ".[dev]"
+      - name: Percy Test
+        uses: percy/exec-action@v0.2.0
+        with:
+          custom-command: "npx percy exec -- python3 test/1.basic_output.py auto"
+        env:
+          PERCY_TOKEN: ${{ secrets.PERCY_TOKEN }}

+ 4 - 0
setup.py

@@ -70,6 +70,10 @@ setup(
     ],
     extras_require={
         'flask': ['flask'],
+        'dev': [
+            'selenium==3.*',
+            'percy-python-selenium',
+        ]
     },
     project_urls={
         'Documentation': 'https://pywebio.readthedocs.io',

+ 128 - 0
test/1.basic_output.py

@@ -0,0 +1,128 @@
+import json
+from functools import partial
+
+import time
+from percy import percySnapshot
+import subprocess
+import pywebio
+from pywebio import start_server
+from pywebio.input import *
+from pywebio.output import *
+from selenium.webdriver import Chrome
+
+
+def basic():
+    set_auto_scroll_bottom(False)
+    set_anchor('top')
+
+    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. 天津
+    
+    [链接](./#)
+    ~~删除线~~
+    """, strip_indent=4, anchor='put_markdown')
+
+    put_text('put_html("<hr/>")')
+    put_html("<hr/>", anchor='put_html')
+
+    put_code(json.dumps(dict(name='pywebio', author='wangweimin'), indent=4), 'json', anchor='put_code')
+
+    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"], anchor='put_table')
+
+    def edit_row(choice, row):
+        put_text("You click %s button at row %s" % (choice, row), after='table_cell_buttons')
+
+    put_table([
+        ['Idx', 'Actions'],
+        ['1', table_cell_buttons(['edit', 'delete'], onclick=partial(edit_row, row=1))],
+        ['2', table_cell_buttons(['edit', 'delete'], onclick=partial(edit_row, row=2))],
+        ['3', table_cell_buttons(['edit', 'delete'], onclick=partial(edit_row, row=3))],
+    ], anchor='table_cell_buttons')
+
+    put_buttons(['A', 'B', 'C'], onclick=partial(put_text, after='put_buttons'), anchor='put_buttons')
+
+    put_image(open("/Users/wangweimin/repos/PyWebIO/docs/assets/input_1.png", 'rb').read(), anchor='put_image')
+
+    put_file('hello_word.txt', b'hello word!', anchor='put_file')
+
+    put_markdown('### 锚点')
+
+    put_text('anchor A1', anchor='A1')
+    put_text('new anchor A1', anchor='A1')
+    put_text('anchor A2', anchor='A2')
+    put_text('anchor A3', anchor='A3')
+
+    put_text('after=A1', after='A1')
+    put_text('after=A2', after='A2')
+    put_text('before=A1', before='A1')
+    put_text('before=A3', before='A3')
+    put_text('after=A3', after='A3')
+
+    clear_range('A1', "A2")
+    clear_range('A3', 'A2')
+    clear_after('A3')
+
+    put_text('before=top', before='top')
+    clear_before('top')
+    put_text('before=top again', before='top')
+
+    put_text('to remove', anchor='to_remove')
+    remove('to_remove')
+
+    hold()
+
+
+def start_test_server():
+    pywebio.enable_debug()
+    start_server(basic, port=8080, debug=True, auto_open_webbrowser=False)
+
+
+def test(server_proc: subprocess.Popen, browser: Chrome):
+    btns = browser.find_elements_by_css_selector('#pywebio-anchor-put_buttons button')
+    for btn in btns:
+        btn.click()
+
+    tab_btns = browser.find_elements_by_css_selector('#pywebio-anchor-table_cell_buttons button')
+    for btn in tab_btns:
+        btn.click()
+
+    time.sleep(1)
+    percySnapshot(browser=browser, name='basic output')
+
+
+if __name__ == '__main__':
+    import util
+
+    util.run_test(start_test_server, test)

+ 11 - 0
test/Readme.md

@@ -0,0 +1,11 @@
+## Test
+
+```bash
+pip3 install -e ".[dev]" 
+npm install --save-dev @percy/agent
+export PERCY_TOKEN=[projects-token]
+
+percy exec -- python3 1.basic_output.py auto
+```
+
+

+ 59 - 0
test/util.py

@@ -0,0 +1,59 @@
+import subprocess
+import sys
+
+from selenium import webdriver
+from pywebio.utils import wait_host_port
+import asyncio
+
+default_chrome_options = webdriver.ChromeOptions()
+default_chrome_options.add_argument('--no-sandbox')
+default_chrome_options.add_argument('--disable-extensions')
+default_chrome_options.add_argument('--disable-dev-shm-usage')
+default_chrome_options.add_argument('--disable-setuid-sandbox')
+
+USAGE = """
+python {name}
+    启动PyWebIO服务器
+
+python {name} auto
+    使用无头浏览器自动化测试
+
+python {name} debug
+    使用带界面的浏览器自动化测试
+"""
+
+
+def run_test(server_func, test_func, port=8080, chrome_options=None):
+    """
+    :param server_func: 启动PyWebIO服务器的函数
+    :param test_func: 测试的函数。人工测试时不会被运行 (server_proc, browser)
+    :param port: 启动的PyWebIO服务器的端口
+    """
+    if len(sys.argv) not in (1, 2) or (len(sys.argv) == 2 and sys.argv[-1] not in ('server', 'auto', 'debug')):
+        print(USAGE.format(name=sys.argv[0]))
+        return
+
+    if len(sys.argv) != 2:
+        server_func()
+        sys.exit()
+
+    proc = subprocess.Popen(['python3', sys.argv[0]], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+    # proc = subprocess.Popen(['python3', sys.argv[0]], stdout=sys.stdout, stderr=subprocess.STDOUT)
+
+    if chrome_options is None:
+        chrome_options = default_chrome_options
+
+    if sys.argv[-1] == 'auto':
+        default_chrome_options.add_argument('--headless')
+
+    if sys.argv[-1] in ('auto', 'debug'):
+        browser = webdriver.Chrome(chrome_options=chrome_options)
+        asyncio.run(wait_host_port('localhost', port))
+        browser.get('http://localhost:%s' % port)
+        browser.implicitly_wait(10)
+        try:
+            test_func(proc, browser)
+        finally:
+            browser.quit()
+            proc.terminate()
+            print("Closed browser and PyWebIO server")