Skip to content

Commit

Permalink
ci: test qt + solara
Browse files Browse the repository at this point in the history
  • Loading branch information
maartenbreddels committed Jul 30, 2024
1 parent 4524180 commit 539fcc0
Show file tree
Hide file tree
Showing 4 changed files with 171 additions and 0 deletions.
79 changes: 79 additions & 0 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,85 @@ jobs:
name: ci-package-locks-pyinstaller-os${{ matrix.os }}-python${{ matrix.python-version }}-ipywidgets${{ matrix.ipywidgets_major }}
path: ./**/${{ env.LOCK_FILE_LOCATION }}

qt-test:
needs: [build]
timeout-minutes: 15
runs-on: ${{ matrix.os }}-latest
strategy:
fail-fast: false
matrix:
os: [macos, windows, ubuntu]
# https://pypi.org/project/PySide6/ seems to have binaries only for python 3.9
python-version: ["3.9"]
env:
LOCK_FILE_LOCATION: .ci-package-locks/qt/os${{ matrix.os }}-python${{ matrix.python-version }}-ipywidgets${{ matrix.ipywidgets_major }}.txt
steps:
- uses: actions/checkout@v4

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: "pip"

- uses: actions/download-artifact@v4
with:
name: solara-builds-${{ github.run_number }}

- name: Link solara app package
if: matrix.os != 'windows'
run: |
cd packages/solara-vuetify-app
npm run devlink
- name: Copy solara app package
if: matrix.os == 'windows'
run: |
cd packages/solara-vuetify-app
npm run wincopy
- name: Prepare
id: prepare
run: |
mkdir test-results
if [ -f ${{ env.LOCK_FILE_LOCATION }} ]; then
echo "LOCKS_EXIST=true" >> "$GITHUB_OUTPUT"
else
echo "LOCKS_EXIST=false" >> "$GITHUB_OUTPUT"
fi
- name: Install without locking versions
if: github.event_name == 'schedule' || steps.prepare.outputs.LOCKS_EXIST == 'false'
id: install_no_lock
run: |
pip install pyside6 qtpy
pip install `echo dist/*.whl`[all]
pip install `echo packages/solara-server/dist/*.whl`[all]
pip install `echo packages/solara-meta/dist/*.whl`[dev,documentation]
pip freeze --exclude solara --exclude solara-ui --exclude solara-server > ${{ env.LOCK_FILE_LOCATION }}
git diff --quiet || echo "HAS_DIFF=true" >> "$GITHUB_OUTPUT"
- name: Install
if: github.event_name != 'schedule' && steps.prepare.outputs.LOCKS_EXIST == 'true'
run: |
pip install -r ${{ env.LOCK_FILE_LOCATION }}
pip install `echo dist/*.whl`[all]
pip install `echo packages/solara-server/dist/*.whl`[all]
pip install `echo packages/solara-meta/dist/*.whl`[dev,documentation]
- name: test qt app
if: github.event_name != 'schedule' || steps.install_no_lock.outputs.HAS_DIFF == 'true'
run: |
python tests/qtapp/solara-qt-test.py
- name: Upload Test artifacts
if: always()
uses: actions/upload-artifact@v4
with:
name: test-results-integration-os${{ matrix.os }}-python${{ matrix.python-version }}-ipywidgets${{ matrix.ipywidgets_major }}
path: test-results

- name: Upload CI package locks
if: steps.install_no_lock.outputs.HAS_DIFF == 'true' || steps.prepare.outputs.LOCKS_EXIST == 'false'
uses: actions/upload-artifact@v4
with:
name: ci-package-locks-integration-os${{ matrix.os }}-python${{ matrix.python-version }}-ipywidgets${{ matrix.ipywidgets_major }}
path: ./**/${{ env.LOCK_FILE_LOCATION }}

integration-test:
needs: [build]
timeout-minutes: 15
Expand Down
64 changes: 64 additions & 0 deletions tests/qtapp/solara-qt-test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import sys
import threading
from time import sleep
from pathlib import Path

import click
import os

# make sure you use pyside when distributing your all without having to use a GPL license
from qtpy.QtWidgets import QApplication
from qtpy.QtWebEngineWidgets import QWebEngineView
from qtpy import QtCore


HERE = Path(__file__).parent


@click.command()
@click.option(
"--port",
default=int(os.environ.get("PORT", 0)),
help="Port to run the server on, 0 for a random free port",
)
def run(port: int):
sys.path.append(str(HERE))
os.environ["SOLARA_APP"] = "test_app"
import test_app

import solara.server.starlette

server = solara.server.starlette.ServerStarlette(host="localhost", port=port)
print(f"Starting server on {server.base_url}")
server.serve_threaded()
server.wait_until_serving()

def test_success(value):
print("test output", value)
app.quit()
server.stop_serving()

test_app.callback = test_success # type: ignore

failed = False

def fail_guard():
sleep(10)
nonlocal failed
print("failed")
app.quit()
failed = True

app = QApplication([""])
web = QWebEngineView()
web.setUrl(QtCore.QUrl(server.base_url))
web.show()

threading.Thread(target=fail_guard, daemon=True).start()
app.exec_()
if failed:
sys.exit(1)


if __name__ == "__main__":
run()
17 changes: 17 additions & 0 deletions tests/qtapp/test_app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import solara


def callback(event):
print("Event received:", event)


@solara.component_vue("test_pywebview.vue")
def TestPywebview(event_callback):
pass


@solara.component
def Page():
TestPywebview(event_callback=callback)
# html = "<script>pywebview.api.test(\"Test passes!\")</script>Script tag inserted"
# solara.HTML(unsafe_innerHTML=html)
11 changes: 11 additions & 0 deletions tests/qtapp/test_pywebview.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<template>
<div>This component should call back to Python</div>
</template>
<script>
module.exports = {
mounted() {
console.log("mounted")
this.callback()
}
}
</script>

0 comments on commit 539fcc0

Please sign in to comment.