remove old raylib screenshot tool (#37225)
This commit is contained in:
175
.github/workflows/raylib_ui_preview.yaml
vendored
175
.github/workflows/raylib_ui_preview.yaml
vendored
@@ -1,175 +0,0 @@
|
||||
name: "raylib ui preview"
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request_target:
|
||||
types: [assigned, opened, synchronize, reopened, edited]
|
||||
branches:
|
||||
- 'master'
|
||||
paths:
|
||||
- 'selfdrive/assets/**'
|
||||
- 'selfdrive/ui/**'
|
||||
- 'system/ui/**'
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
UI_JOB_NAME: "Create raylib UI Report"
|
||||
REPORT_NAME: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' && 'master' || github.event.number }}
|
||||
SHA: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' && github.sha || github.event.pull_request.head.sha }}
|
||||
BRANCH_NAME: "openpilot/pr-${{ github.event.number }}-raylib-ui"
|
||||
|
||||
jobs:
|
||||
preview:
|
||||
if: github.repository == 'commaai/openpilot'
|
||||
name: preview
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 20
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
actions: read
|
||||
steps:
|
||||
- name: Waiting for ui generation to start
|
||||
run: sleep 30
|
||||
|
||||
- name: Waiting for ui generation to end
|
||||
uses: lewagon/wait-on-check-action@v1.3.4
|
||||
with:
|
||||
ref: ${{ env.SHA }}
|
||||
check-name: ${{ env.UI_JOB_NAME }}
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
allowed-conclusions: success
|
||||
wait-interval: 20
|
||||
|
||||
- name: Getting workflow run ID
|
||||
id: get_run_id
|
||||
run: |
|
||||
echo "run_id=$(curl https://api.github.com/repos/${{ github.repository }}/commits/${{ env.SHA }}/check-runs | jq -r '.check_runs[] | select(.name == "${{ env.UI_JOB_NAME }}") | .html_url | capture("(?<number>[0-9]+)") | .number')" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Getting proposed ui
|
||||
id: download-artifact
|
||||
uses: dawidd6/action-download-artifact@v6
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
run_id: ${{ steps.get_run_id.outputs.run_id }}
|
||||
search_artifacts: true
|
||||
name: raylib-report-1-${{ env.REPORT_NAME }}
|
||||
path: ${{ github.workspace }}/pr_ui
|
||||
|
||||
- name: Getting master ui
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
repository: commaai/ci-artifacts
|
||||
ssh-key: ${{ secrets.CI_ARTIFACTS_DEPLOY_KEY }}
|
||||
path: ${{ github.workspace }}/master_ui_raylib
|
||||
ref: openpilot_master_ui_raylib
|
||||
|
||||
- name: Saving new master ui
|
||||
if: github.ref == 'refs/heads/master' && github.event_name == 'push'
|
||||
working-directory: ${{ github.workspace }}/master_ui_raylib
|
||||
run: |
|
||||
git checkout --orphan=new_master_ui_raylib
|
||||
git rm -rf *
|
||||
git branch -D openpilot_master_ui_raylib
|
||||
git branch -m openpilot_master_ui_raylib
|
||||
git config user.name "GitHub Actions Bot"
|
||||
git config user.email "<>"
|
||||
mv ${{ github.workspace }}/pr_ui/*.png .
|
||||
git add .
|
||||
git commit -m "raylib screenshots for commit ${{ env.SHA }}"
|
||||
git push origin openpilot_master_ui_raylib --force
|
||||
|
||||
- name: Finding diff
|
||||
if: github.event_name == 'pull_request_target'
|
||||
id: find_diff
|
||||
run: >-
|
||||
sudo apt-get update && sudo apt-get install -y imagemagick
|
||||
|
||||
scenes=$(find ${{ github.workspace }}/pr_ui/*.png -type f -printf "%f\n" | cut -d '.' -f 1 | grep -v 'pair_device')
|
||||
A=($scenes)
|
||||
|
||||
DIFF=""
|
||||
TABLE="<details><summary>All Screenshots</summary>"
|
||||
TABLE="${TABLE}<table>"
|
||||
|
||||
for ((i=0; i<${#A[*]}; i=i+1));
|
||||
do
|
||||
# Check if the master file exists
|
||||
if [ ! -f "${{ github.workspace }}/master_ui_raylib/${A[$i]}.png" ]; then
|
||||
# This is a new file in PR UI that doesn't exist in master
|
||||
DIFF="${DIFF}<details open>"
|
||||
DIFF="${DIFF}<summary>${A[$i]} : \$\${\\color{cyan}\\text{NEW}}\$\$</summary>"
|
||||
DIFF="${DIFF}<table>"
|
||||
|
||||
DIFF="${DIFF}<tr>"
|
||||
DIFF="${DIFF} <td> <img src=\"https://raw.githubusercontent.com/commaai/ci-artifacts/${{ env.BRANCH_NAME }}/${A[$i]}.png\"> </td>"
|
||||
DIFF="${DIFF}</tr>"
|
||||
|
||||
DIFF="${DIFF}</table>"
|
||||
DIFF="${DIFF}</details>"
|
||||
elif ! compare -fuzz 2% -highlight-color DeepSkyBlue1 -lowlight-color Black -compose Src ${{ github.workspace }}/master_ui_raylib/${A[$i]}.png ${{ github.workspace }}/pr_ui/${A[$i]}.png ${{ github.workspace }}/pr_ui/${A[$i]}_diff.png; then
|
||||
convert ${{ github.workspace }}/pr_ui/${A[$i]}_diff.png -transparent black mask.png
|
||||
composite mask.png ${{ github.workspace }}/master_ui_raylib/${A[$i]}.png composite_diff.png
|
||||
convert -delay 100 ${{ github.workspace }}/master_ui_raylib/${A[$i]}.png composite_diff.png -loop 0 ${{ github.workspace }}/pr_ui/${A[$i]}_diff.gif
|
||||
|
||||
mv ${{ github.workspace }}/master_ui_raylib/${A[$i]}.png ${{ github.workspace }}/pr_ui/${A[$i]}_master_ref.png
|
||||
|
||||
DIFF="${DIFF}<details open>"
|
||||
DIFF="${DIFF}<summary>${A[$i]} : \$\${\\color{red}\\text{DIFFERENT}}\$\$</summary>"
|
||||
DIFF="${DIFF}<table>"
|
||||
|
||||
DIFF="${DIFF}<tr>"
|
||||
DIFF="${DIFF} <td> master <img src=\"https://raw.githubusercontent.com/commaai/ci-artifacts/${{ env.BRANCH_NAME }}/${A[$i]}_master_ref.png\"> </td>"
|
||||
DIFF="${DIFF} <td> proposed <img src=\"https://raw.githubusercontent.com/commaai/ci-artifacts/${{ env.BRANCH_NAME }}/${A[$i]}.png\"> </td>"
|
||||
DIFF="${DIFF}</tr>"
|
||||
|
||||
DIFF="${DIFF}<tr>"
|
||||
DIFF="${DIFF} <td> diff <img src=\"https://raw.githubusercontent.com/commaai/ci-artifacts/${{ env.BRANCH_NAME }}/${A[$i]}_diff.png\"> </td>"
|
||||
DIFF="${DIFF} <td> composite diff <img src=\"https://raw.githubusercontent.com/commaai/ci-artifacts/${{ env.BRANCH_NAME }}/${A[$i]}_diff.gif\"> </td>"
|
||||
DIFF="${DIFF}</tr>"
|
||||
|
||||
DIFF="${DIFF}</table>"
|
||||
DIFF="${DIFF}</details>"
|
||||
else
|
||||
rm -f ${{ github.workspace }}/pr_ui/${A[$i]}_diff.png
|
||||
fi
|
||||
|
||||
INDEX=$(($i % 2))
|
||||
if [[ $INDEX -eq 0 ]]; then
|
||||
TABLE="${TABLE}<tr>"
|
||||
fi
|
||||
TABLE="${TABLE} <td> <img src=\"https://raw.githubusercontent.com/commaai/ci-artifacts/${{ env.BRANCH_NAME }}/${A[$i]}.png\"> </td>"
|
||||
if [[ $INDEX -eq 1 || $(($i + 1)) -eq ${#A[*]} ]]; then
|
||||
TABLE="${TABLE}</tr>"
|
||||
fi
|
||||
done
|
||||
|
||||
TABLE="${TABLE}</table></details>"
|
||||
|
||||
echo "DIFF=$DIFF$TABLE" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Saving proposed ui
|
||||
if: github.event_name == 'pull_request_target'
|
||||
working-directory: ${{ github.workspace }}/master_ui_raylib
|
||||
run: |
|
||||
git config user.name "GitHub Actions Bot"
|
||||
git config user.email "<>"
|
||||
git checkout --orphan=${{ env.BRANCH_NAME }}
|
||||
git rm -rf *
|
||||
mv ${{ github.workspace }}/pr_ui/* .
|
||||
git add .
|
||||
git commit -m "raylib screenshots for PR #${{ github.event.number }}"
|
||||
git push origin ${{ env.BRANCH_NAME }} --force
|
||||
|
||||
- name: Comment Screenshots on PR
|
||||
if: github.event_name == 'pull_request_target'
|
||||
uses: thollander/actions-comment-pull-request@v2
|
||||
with:
|
||||
message: |
|
||||
<!-- _(run_id_screenshots_raylib **${{ github.run_id }}**)_ -->
|
||||
## raylib UI Preview
|
||||
${{ steps.find_diff.outputs.DIFF }}
|
||||
comment_tag: run_id_screenshots_raylib
|
||||
pr_number: ${{ github.event.number }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
26
.github/workflows/tests.yaml
vendored
26
.github/workflows/tests.yaml
vendored
@@ -255,32 +255,6 @@ jobs:
|
||||
source selfdrive/test/setup_vsound.sh && \
|
||||
CI=1 pytest -s tools/sim/tests/test_metadrive_bridge.py"
|
||||
|
||||
create_raylib_ui_report:
|
||||
name: Create raylib UI Report
|
||||
runs-on: ${{
|
||||
(github.repository == 'commaai/openpilot') &&
|
||||
((github.event_name != 'pull_request') ||
|
||||
(github.event.pull_request.head.repo.full_name == 'commaai/openpilot'))
|
||||
&& fromJSON('["namespace-profile-amd64-8x16", "namespace-experiments:docker.builds.local-cache=separate"]')
|
||||
|| fromJSON('["ubuntu-24.04"]') }}
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
submodules: true
|
||||
- uses: ./.github/workflows/setup-with-retry
|
||||
- name: Build openpilot
|
||||
run: ${{ env.RUN }} "scons -j$(nproc)"
|
||||
- name: Create raylib UI Report
|
||||
run: >
|
||||
${{ env.RUN }} "PYTHONWARNINGS=ignore &&
|
||||
source selfdrive/test/setup_xvfb.sh &&
|
||||
python3 selfdrive/ui/tests/test_ui/raylib_screenshots.py"
|
||||
- name: Upload Raylib UI Report
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: raylib-report-${{ inputs.run_number || '1' }}-${{ github.event_name == 'push' && github.ref == 'refs/heads/master' && 'master' || github.event.number }}
|
||||
path: selfdrive/ui/tests/test_ui/raylib_report/screenshots
|
||||
|
||||
create_mici_raylib_ui_report:
|
||||
name: Create mici raylib UI Report
|
||||
runs-on: ${{
|
||||
|
||||
@@ -100,8 +100,6 @@ dev = [
|
||||
"matplotlib",
|
||||
"opencv-python-headless",
|
||||
"parameterized >=0.8, <0.9",
|
||||
"pyautogui",
|
||||
"pywinctl",
|
||||
]
|
||||
|
||||
tools = [
|
||||
|
||||
1
selfdrive/ui/tests/.gitignore
vendored
1
selfdrive/ui/tests/.gitignore
vendored
@@ -1,7 +1,6 @@
|
||||
test
|
||||
test_translations
|
||||
test_ui/report_1
|
||||
test_ui/raylib_report
|
||||
|
||||
diff/**/*.mp4
|
||||
diff/**/*.html
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Simple script to print mouse coordinates on Ubuntu.
|
||||
Run with: python print_mouse_coords.py
|
||||
Press Ctrl+C to exit.
|
||||
"""
|
||||
|
||||
from pynput import mouse
|
||||
|
||||
print("Mouse coordinate printer - Press Ctrl+C to exit")
|
||||
print("Click to set the top left origin")
|
||||
|
||||
origin: tuple[int, int] | None = None
|
||||
clicks: list[tuple[int, int]] = []
|
||||
|
||||
|
||||
def on_click(x, y, button, pressed):
|
||||
global origin, clicks
|
||||
if pressed: # Only on mouse down, not up
|
||||
if origin is None:
|
||||
origin = (x, y)
|
||||
print(f"Origin set to: {x},{y}")
|
||||
else:
|
||||
rel_x = x - origin[0]
|
||||
rel_y = y - origin[1]
|
||||
clicks.append((rel_x, rel_y))
|
||||
print(f"Clicks: {clicks}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
# Start mouse listener
|
||||
with mouse.Listener(on_click=on_click) as listener:
|
||||
listener.join()
|
||||
except KeyboardInterrupt:
|
||||
print("\nExiting...")
|
||||
@@ -1,317 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
import os
|
||||
import sys
|
||||
import shutil
|
||||
import time
|
||||
import pathlib
|
||||
from collections import namedtuple
|
||||
|
||||
import pyautogui
|
||||
import pywinctl
|
||||
|
||||
from cereal import car, log
|
||||
from cereal import messaging
|
||||
from cereal.messaging import PubMaster
|
||||
from openpilot.common.basedir import BASEDIR
|
||||
from openpilot.common.params import Params
|
||||
from openpilot.common.prefix import OpenpilotPrefix
|
||||
from openpilot.selfdrive.test.helpers import with_processes
|
||||
from openpilot.selfdrive.selfdrived.alertmanager import set_offroad_alert
|
||||
from openpilot.system.updated.updated import parse_release_notes
|
||||
from openpilot.system.version import terms_version, training_version
|
||||
|
||||
AlertSize = log.SelfdriveState.AlertSize
|
||||
AlertStatus = log.SelfdriveState.AlertStatus
|
||||
|
||||
TEST_DIR = pathlib.Path(__file__).parent
|
||||
TEST_OUTPUT_DIR = TEST_DIR / "raylib_report"
|
||||
SCREENSHOTS_DIR = TEST_OUTPUT_DIR / "screenshots"
|
||||
UI_DELAY = 0.5
|
||||
|
||||
BRANCH_NAME = "this-is-a-really-super-mega-ultra-max-extreme-ultimate-long-branch-name"
|
||||
VERSION = f"0.10.1 / {BRANCH_NAME} / 7864838 / Oct 03"
|
||||
|
||||
# Offroad alerts to test
|
||||
OFFROAD_ALERTS = ['Offroad_IsTakingSnapshot']
|
||||
|
||||
|
||||
def put_update_params(params: Params):
|
||||
params.put("UpdaterCurrentReleaseNotes", parse_release_notes(BASEDIR))
|
||||
params.put("UpdaterNewReleaseNotes", parse_release_notes(BASEDIR))
|
||||
params.put("UpdaterTargetBranch", BRANCH_NAME)
|
||||
|
||||
|
||||
def setup_homescreen(click, pm: PubMaster):
|
||||
pass
|
||||
|
||||
|
||||
def setup_homescreen_update_available(click, pm: PubMaster):
|
||||
params = Params()
|
||||
params.put_bool("UpdateAvailable", True)
|
||||
put_update_params(params)
|
||||
setup_offroad_alert(click, pm)
|
||||
|
||||
|
||||
def setup_settings(click, pm: PubMaster):
|
||||
click(100, 100)
|
||||
|
||||
|
||||
def close_settings(click, pm: PubMaster):
|
||||
click(240, 216)
|
||||
|
||||
|
||||
def setup_settings_network(click, pm: PubMaster):
|
||||
setup_settings(click, pm)
|
||||
click(278, 450)
|
||||
|
||||
|
||||
def setup_settings_network_advanced(click, pm: PubMaster):
|
||||
setup_settings_network(click, pm)
|
||||
click(1880, 100)
|
||||
|
||||
|
||||
def setup_settings_toggles(click, pm: PubMaster):
|
||||
setup_settings(click, pm)
|
||||
click(278, 600)
|
||||
|
||||
|
||||
def setup_settings_software(click, pm: PubMaster):
|
||||
put_update_params(Params())
|
||||
setup_settings(click, pm)
|
||||
click(278, 720)
|
||||
|
||||
|
||||
def setup_settings_software_download(click, pm: PubMaster):
|
||||
params = Params()
|
||||
# setup_settings_software but with "DOWNLOAD" button to test long text
|
||||
params.put("UpdaterState", "idle")
|
||||
params.put_bool("UpdaterFetchAvailable", True)
|
||||
setup_settings_software(click, pm)
|
||||
|
||||
|
||||
def setup_settings_software_release_notes(click, pm: PubMaster):
|
||||
setup_settings_software(click, pm)
|
||||
click(588, 110) # expand description for current version
|
||||
|
||||
|
||||
def setup_settings_software_branch_switcher(click, pm: PubMaster):
|
||||
setup_settings_software(click, pm)
|
||||
params = Params()
|
||||
params.put("UpdaterAvailableBranches", f"master,nightly,release,{BRANCH_NAME}")
|
||||
params.put("GitBranch", BRANCH_NAME) # should be on top
|
||||
params.put("UpdaterTargetBranch", "nightly") # should be selected
|
||||
click(1984, 449)
|
||||
|
||||
|
||||
def setup_settings_firehose(click, pm: PubMaster):
|
||||
setup_settings(click, pm)
|
||||
click(278, 845)
|
||||
|
||||
|
||||
def setup_settings_developer(click, pm: PubMaster):
|
||||
CP = car.CarParams()
|
||||
CP.alphaLongitudinalAvailable = True # show alpha long control toggle
|
||||
Params().put("CarParamsPersistent", CP.to_bytes())
|
||||
|
||||
setup_settings(click, pm)
|
||||
click(278, 950)
|
||||
|
||||
|
||||
def setup_keyboard(click, pm: PubMaster):
|
||||
setup_settings_developer(click, pm)
|
||||
click(1930, 470)
|
||||
|
||||
|
||||
def setup_pair_device(click, pm: PubMaster):
|
||||
click(1950, 800)
|
||||
|
||||
|
||||
def setup_offroad_alert(click, pm: PubMaster):
|
||||
put_update_params(Params())
|
||||
set_offroad_alert("Offroad_TemperatureTooHigh", True, extra_text='99C')
|
||||
set_offroad_alert("Offroad_ExcessiveActuation", True, extra_text='longitudinal')
|
||||
for alert in OFFROAD_ALERTS:
|
||||
set_offroad_alert(alert, True)
|
||||
|
||||
setup_settings(click, pm)
|
||||
close_settings(click, pm)
|
||||
|
||||
|
||||
def setup_confirmation_dialog(click, pm: PubMaster):
|
||||
setup_settings(click, pm)
|
||||
click(1985, 791) # reset calibration
|
||||
|
||||
|
||||
def setup_experimental_mode_description(click, pm: PubMaster):
|
||||
setup_settings_toggles(click, pm)
|
||||
click(1200, 280) # expand description for experimental mode
|
||||
|
||||
|
||||
def setup_openpilot_long_confirmation_dialog(click, pm: PubMaster):
|
||||
setup_settings_developer(click, pm)
|
||||
click(2000, 960) # toggle openpilot longitudinal control
|
||||
|
||||
|
||||
def setup_onroad(click, pm: PubMaster):
|
||||
ds = messaging.new_message('deviceState')
|
||||
ds.deviceState.started = True
|
||||
|
||||
ps = messaging.new_message('pandaStates', 1)
|
||||
ps.pandaStates[0].pandaType = log.PandaState.PandaType.dos
|
||||
ps.pandaStates[0].ignitionLine = True
|
||||
|
||||
driverState = messaging.new_message('driverStateV2')
|
||||
driverState.driverStateV2.leftDriverData.faceOrientation = [0, 0, 0]
|
||||
|
||||
for _ in range(5):
|
||||
pm.send('deviceState', ds)
|
||||
pm.send('pandaStates', ps)
|
||||
pm.send('driverStateV2', driverState)
|
||||
ds.clear_write_flag()
|
||||
ps.clear_write_flag()
|
||||
driverState.clear_write_flag()
|
||||
time.sleep(0.05)
|
||||
|
||||
|
||||
def setup_onroad_sidebar(click, pm: PubMaster):
|
||||
setup_onroad(click, pm)
|
||||
click(100, 100) # open sidebar
|
||||
|
||||
|
||||
def setup_onroad_alert(click, pm: PubMaster, size: log.SelfdriveState.AlertSize, text1: str, text2: str, status: log.SelfdriveState.AlertStatus):
|
||||
setup_onroad(click, pm)
|
||||
alert = messaging.new_message('selfdriveState')
|
||||
ss = alert.selfdriveState
|
||||
ss.alertSize = size
|
||||
ss.alertText1 = text1
|
||||
ss.alertText2 = text2
|
||||
ss.alertStatus = status
|
||||
for _ in range(5):
|
||||
pm.send('selfdriveState', alert)
|
||||
alert.clear_write_flag()
|
||||
time.sleep(0.05)
|
||||
|
||||
|
||||
def setup_onroad_small_alert(click, pm: PubMaster):
|
||||
setup_onroad_alert(click, pm, AlertSize.small, "Small Alert", "This is a small alert", AlertStatus.normal)
|
||||
|
||||
|
||||
def setup_onroad_medium_alert(click, pm: PubMaster):
|
||||
setup_onroad_alert(click, pm, AlertSize.mid, "Medium Alert", "This is a medium alert", AlertStatus.userPrompt)
|
||||
|
||||
|
||||
def setup_onroad_full_alert(click, pm: PubMaster):
|
||||
setup_onroad_alert(click, pm, AlertSize.full, "DISENGAGE IMMEDIATELY", "Driver Distracted", AlertStatus.critical)
|
||||
|
||||
|
||||
def setup_onroad_full_alert_multiline(click, pm: PubMaster):
|
||||
setup_onroad_alert(click, pm, AlertSize.full, "Reverse\nGear", "", AlertStatus.normal)
|
||||
|
||||
|
||||
def setup_onroad_full_alert_long_text(click, pm: PubMaster):
|
||||
setup_onroad_alert(click, pm, AlertSize.full, "TAKE CONTROL IMMEDIATELY", "Calibration Invalid: Remount Device & Recalibrate", AlertStatus.userPrompt)
|
||||
|
||||
|
||||
CASES = {
|
||||
"homescreen": setup_homescreen,
|
||||
"homescreen_paired": setup_homescreen,
|
||||
"homescreen_prime": setup_homescreen,
|
||||
"homescreen_update_available": setup_homescreen_update_available,
|
||||
"homescreen_unifont": setup_homescreen,
|
||||
"settings_device": setup_settings,
|
||||
"settings_network": setup_settings_network,
|
||||
"settings_network_advanced": setup_settings_network_advanced,
|
||||
"settings_toggles": setup_settings_toggles,
|
||||
"settings_software": setup_settings_software,
|
||||
"settings_software_download": setup_settings_software_download,
|
||||
"settings_software_release_notes": setup_settings_software_release_notes,
|
||||
"settings_software_branch_switcher": setup_settings_software_branch_switcher,
|
||||
"settings_firehose": setup_settings_firehose,
|
||||
"settings_developer": setup_settings_developer,
|
||||
"keyboard": setup_keyboard,
|
||||
"pair_device": setup_pair_device,
|
||||
"offroad_alert": setup_offroad_alert,
|
||||
"confirmation_dialog": setup_confirmation_dialog,
|
||||
"experimental_mode_description": setup_experimental_mode_description,
|
||||
"openpilot_long_confirmation_dialog": setup_openpilot_long_confirmation_dialog,
|
||||
"onroad": setup_onroad,
|
||||
"onroad_sidebar": setup_onroad_sidebar,
|
||||
"onroad_small_alert": setup_onroad_small_alert,
|
||||
"onroad_medium_alert": setup_onroad_medium_alert,
|
||||
"onroad_full_alert": setup_onroad_full_alert,
|
||||
"onroad_full_alert_multiline": setup_onroad_full_alert_multiline,
|
||||
"onroad_full_alert_long_text": setup_onroad_full_alert_long_text,
|
||||
}
|
||||
|
||||
|
||||
class TestUI:
|
||||
def __init__(self):
|
||||
os.environ["SCALE"] = os.getenv("SCALE", "1")
|
||||
os.environ["BIG"] = "1"
|
||||
sys.modules["mouseinfo"] = False
|
||||
|
||||
def setup(self):
|
||||
# Seed minimal offroad state
|
||||
self.pm = PubMaster(["deviceState", "pandaStates", "driverStateV2", "selfdriveState"])
|
||||
ds = messaging.new_message('deviceState')
|
||||
ds.deviceState.networkType = log.DeviceState.NetworkType.wifi
|
||||
for _ in range(5):
|
||||
self.pm.send('deviceState', ds)
|
||||
ds.clear_write_flag()
|
||||
time.sleep(0.05)
|
||||
time.sleep(0.5)
|
||||
try:
|
||||
self.ui = pywinctl.getWindowsWithTitle("UI")[0]
|
||||
except Exception as e:
|
||||
print(f"failed to find ui window, assuming that it's in the top left (for Xvfb) {e}")
|
||||
self.ui = namedtuple("bb", ["left", "top", "width", "height"])(0, 0, 2160, 1080)
|
||||
|
||||
def screenshot(self, name: str):
|
||||
full_screenshot = pyautogui.screenshot()
|
||||
cropped = full_screenshot.crop((self.ui.left, self.ui.top, self.ui.left + self.ui.width, self.ui.top + self.ui.height))
|
||||
cropped.save(SCREENSHOTS_DIR / f"{name}.png")
|
||||
|
||||
def click(self, x: int, y: int, *args, **kwargs):
|
||||
pyautogui.mouseDown(self.ui.left + x, self.ui.top + y, *args, **kwargs)
|
||||
time.sleep(0.01)
|
||||
pyautogui.mouseUp(self.ui.left + x, self.ui.top + y, *args, **kwargs)
|
||||
|
||||
@with_processes(["ui"])
|
||||
def test_ui(self, name, setup_case):
|
||||
self.setup()
|
||||
time.sleep(UI_DELAY) # wait for UI to start
|
||||
setup_case(self.click, self.pm)
|
||||
self.screenshot(name)
|
||||
|
||||
|
||||
def create_screenshots():
|
||||
if TEST_OUTPUT_DIR.exists():
|
||||
shutil.rmtree(TEST_OUTPUT_DIR)
|
||||
SCREENSHOTS_DIR.mkdir(parents=True)
|
||||
|
||||
t = TestUI()
|
||||
for name, setup in CASES.items():
|
||||
with OpenpilotPrefix():
|
||||
params = Params()
|
||||
params.put("DongleId", "123456789012345")
|
||||
|
||||
# Set branch name
|
||||
params.put("UpdaterCurrentDescription", VERSION)
|
||||
params.put("UpdaterNewDescription", VERSION)
|
||||
|
||||
# Set terms and training version (to skip onboarding)
|
||||
params.put("HasAcceptedTerms", terms_version)
|
||||
params.put("CompletedTrainingVersion", training_version)
|
||||
|
||||
if name == "homescreen_paired":
|
||||
params.put("PrimeType", 0) # NONE
|
||||
elif name == "homescreen_prime":
|
||||
params.put("PrimeType", 2) # LITE
|
||||
elif name == "homescreen_unifont":
|
||||
params.put("LanguageSetting", "zh-CHT") # Traditional Chinese
|
||||
|
||||
t.test_ui(name, setup)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
create_screenshots()
|
||||
@@ -1,34 +0,0 @@
|
||||
<html>
|
||||
|
||||
<style>
|
||||
.column {
|
||||
float: left;
|
||||
width: 50%;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.row::after {
|
||||
content: "";
|
||||
clear: both;
|
||||
display: table;
|
||||
}
|
||||
|
||||
.image {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
{% for name, (image, ref_image) in cases.items() %}
|
||||
|
||||
<h1>{{name}}</h1>
|
||||
<div class="row">
|
||||
<div class="column">
|
||||
<img class="image" src="{{ image }}" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
{% endfor %}
|
||||
</html>
|
||||
@@ -1,8 +1,6 @@
|
||||
#!/usr/bin/env python3
|
||||
import argparse
|
||||
import os
|
||||
import pyautogui
|
||||
import subprocess
|
||||
import dearpygui.dearpygui as dpg
|
||||
import multiprocessing
|
||||
import uuid
|
||||
@@ -316,11 +314,12 @@ def main(route_to_load=None, layout_to_load=None):
|
||||
dpg.create_context()
|
||||
|
||||
# TODO: find better way of calculating display scaling
|
||||
try:
|
||||
w, h = next(tuple(map(int, l.split()[0].split('x'))) for l in subprocess.check_output(['xrandr']).decode().split('\n') if '*' in l) # actual resolution
|
||||
scale = pyautogui.size()[0] / w # scaled resolution
|
||||
except Exception:
|
||||
scale = 1
|
||||
#try:
|
||||
# w, h = next(tuple(map(int, l.split()[0].split('x'))) for l in subprocess.check_output(['xrandr']).decode().split('\n') if '*' in l) # actual resolution
|
||||
# scale = pyautogui.size()[0] / w # scaled resolution
|
||||
#except Exception:
|
||||
# scale = 1
|
||||
scale = 1
|
||||
|
||||
with dpg.font_registry():
|
||||
default_font = dpg.add_font(os.path.join(BASEDIR, "selfdrive/assets/fonts/JetBrainsMono-Medium.ttf"), int(13 * scale * 2)) # 2x then scale for hidpi
|
||||
@@ -328,9 +327,8 @@ def main(route_to_load=None, layout_to_load=None):
|
||||
dpg.set_global_font_scale(0.5)
|
||||
|
||||
viewport_width, viewport_height = int(1200 * scale), int(800 * scale)
|
||||
mouse_x, mouse_y = pyautogui.position() # TODO: find better way of creating the window where the user is (default dpg behavior annoying on multiple displays)
|
||||
dpg.create_viewport(
|
||||
title='JotPluggler', width=viewport_width, height=viewport_height, x_pos=mouse_x - viewport_width // 2, y_pos=mouse_y - viewport_height // 2
|
||||
title='JotPluggler', width=viewport_width, height=viewport_height,
|
||||
)
|
||||
dpg.setup_dearpygui()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user