Manual GUI check before a release
The tests check what the renderer draws (graphics data per item, low-resolution raytracer images, #2704). Nothing automatic checks that a person can use the render window and the dialogs: keys, mouse, tkinter windows, focus, fonts, window placement. That is this list.
Once per release on each of Windows, Ubuntu and macOS; one person, about one hour.
Do only what is written; if something looks wrong, note it and go on.
Not checked here: what each setting draws (automatic). Checked here: that the key or the dialog reaches the renderer - one or two settings per path.
0. Preparation (5 min)
Install the release candidate wheel into a clean environment (
pip install exudyn-<version>-...whl).Run
python -m exudyn infoand paste the output into the report.Back up
~/.exudyn/config.jsonif it exists, then delete it, so that you test the defaults. Some checks below write this file; restore your backup at the end.Copy
python/testing/guiManualCheckModel.py,python/Examples/nMassOscillatorEigenmodes.pyandpython/Examples/graphicsCurvedShapes.pyinto an empty working directory, and run everything from there in a terminal (not from an IDE): images and files are written relative to it.python -m exudyn demo 2- the renderer opens, the demo runs, the window closes (demoalone is demo 1, without graphics). If this fails, stop here and report it.
Which model: sections 1 to 4 and 6 use guiManualCheckModel.py, K13 graphicsCurvedShapes.py,
section 5 nMassOscillatorEigenmodes.py, O3 mouseInteractionExample.py; each section says it again.
Model used: guiManualCheckModel.py - a mass point with spring-damper and force, and a 3D double
pendulum of two rigid bodies with revolute joints; it has at least one node, body, connector,
marker, load and sensor, and a sensor trace; the red mass is drawn as its node, the orange sphere on
the second link with general.sphereTiling. It opens the renderer and waits; SPACE starts a
real-time simulation of 120 s, Q stops it, then SolutionViewer and PlotSensor follow; the script
ends when the plot windows are closed.
Report each check as OK / FAIL / n.a. with the ID; for a FAIL, one line on what happened.
1. Render window: mouse and view keys (15 min)
python guiManualCheckModel.py - the window opens, the model is not moving yet.
ID |
action |
expected |
|---|---|---|
R1 |
look at the window after start |
model fully visible (zoom all), help hint shown for ~5 s, window title and status text readable (display scaling!) |
R2 |
left mouse: press, drag, release |
model moves with the mouse in the screen plane |
R3 |
right mouse: press, drag, release |
model rotates about the screen axes; release stops it |
R4 |
mouse wheel up/down; with CTRL |
zoom in/out; CTRL gives small steps |
R5 |
left click (no drag) on the red mass; then on empty space |
status line Selected item: …; item highlighted for ~2 s; empty space: no item selected |
R6 |
right click (no drag) on a pendulum link |
read-only dialog properties of <…> opens with the item dictionary; ESCAPE closes it; render window still reacts afterwards |
R7 |
keys |
zoom all, zoom in, zoom out |
R8 |
cursor keys; CTRL+cursor; SHIFT+cursor; ALT+LEFT/RIGHT |
move; small move; rotate about screen x/y; rotate about screen z |
R9 |
keypad 2/8, 4/6, 7/9 (if a keypad exists); same with CTRL |
rotation about 1, 2, 3 axis; CTRL: small rotation |
R10 |
CTRL+1 … CTRL+7, then SHIFT+CTRL+1 |
the standard views (1-2 plane, 1-3, 2-3, …, 3D view); SHIFT: the same plane from behind; a message names the view |
R11 |
pan with left mouse so that the pendulum joint is at the window center, press |
message Set rotationCenterPoint …; the model now rotates about the new center |
R12 |
|
automatic rotation of the view starts and stops |
R13 |
F3, then left-click twice at two points (after CTRL+1) |
mouse coordinates in the status line; second click shows |
R14 |
CTRL+F3 (macOS: n.a. if the system shortcut Move focus to the Dock is on; then V, store model view) |
status line shows zoom / rotation / center; the console prints a |
2. Render window: item keys, simulation keys, raytracer, views (10 min)
ID |
action |
expected |
|---|---|---|
K1 |
|
nodes / bodies / connectors / markers / loads / sensors disappear and reappear; a message says show …: off/on; the markers sit inside the bodies and are seen with the bodies off |
K2 |
CTRL+ |
the numbers of that item kind appear/disappear; text readable, not hidden behind the bodies |
K3 |
|
cycles through transparent faces / face edges only / faces with edges / … and back to the start; message states the mode |
K4 |
SPACE |
simulation starts in real time; the sensor trace of the pendulum tip is drawn |
K5 |
SPACE again, wait, SPACE |
simulation pauses and continues (message switch pause on/off) |
K6 |
during simulation: |
update interval 20 ms (smooth), 100 s (frozen), 100 ms (default) - message each time |
K7 |
CTRL+R, rotate a little, CTRL+R |
raytraced image (shadows, slower update) with the sensor trace, then back to OpenGL |
K8 |
CTRL+V |
a second window (view 1) opens and shows the running model; mouse and keys work in it independently; CTRL+R there only affects that window |
K9 |
in the view 1 window: |
only view 1 closes, the simulation continues in the main window |
K10 |
F2, then |
message ignore keys mode switched on, the first |
K11 |
|
simulation stops; console prints simulation finished …; the window stays and can still be rotated |
K12 |
|
the shadow of the pendulum stays where the light puts it and follows the view smoothly - it does not flicker or appear and vanish with the view (#2308); set the three back |
K13 |
run |
the curved row (y=0) is smooth where the flat row (y=-3) shows facets, the red rims lie on the cylinder and the vase; at 90 the coarse elements show, at 5 a fine split - at once, without restarting; the face edges of the curved shapes are curved; the raytraced image shows the same shapes; the body at x=12 rotates with its rims and ring (#2709) |
3. Dialogs from the render window (15 min)
Still in phase 3 of the model (after K11), or start the model again.
ID |
action |
expected |
|---|---|---|
D1 |
|
help window with mouse and key table; text readable, scrollable, ESCAPE closes it |
D2 |
|
command window opens (may be behind the render window - note it); the console shows the system summary |
D3 |
in the command window: |
prints 42 (assignments survive); window closes |
D4 |
|
error printed in the console, the dialog and the renderer survive |
V1 |
|
visualization settings dialog: tree with columns Name / Value / Type / Description, readable font, sensible column widths; render window blocked or updated while it is open (both are acceptable, note which) |
V2 |
open |
nodes disappear in the render window immediately; the row is marked as changed |
V3 |
double-click the same |
toggles back to |
V4 |
|
the red mass (a node) grows in the render window |
V5 |
|
first the red mass, then the orange sphere and the joint spheres become visibly coarse; set both back with undo |
V6 |
|
joint axes drawn; body numbers shown |
V6a |
|
the spring windings become a tube; markers, loads and sensors drawn with their full symbols; back to lines and simple symbols |
V7 |
enter an invalid value, e.g. |
value rejected with a message, old value kept, dialog survives |
V8 |
enum: |
combo box shows short names (no |
V9 |
hover over a row and over a folder (wait 0.5 s) |
tooltip with the description (folder: its class description); tooltip is in front of the dialog |
V10 |
CTRL+F, type |
hits drop-down enabled; RETURN jumps to the first hit, F3 to the next |
V11 |
select a row, press copy line, paste into an editor |
e.g. |
V12 |
diff to default, changes since start |
each opens a window in front of the dialog, listing exactly the changes made so far as code lines |
V13 |
undo (twice), revert, reset |
undo steps back whole states; revert returns to the state when the dialog opened; reset to defaults - render window follows each |
V14 |
change |
the list shows the change; console says stored 1 setting(s) in …config.json |
V15 |
move/resize the dialog, press store positions, then store in the list; close with ESCAPE; |
the dialog reopens at the stored position and size |
V16 |
CTRL+mouse wheel over the tree |
font size changes, row height and columns follow |
V17 |
close the dialog with close, then |
render window closes; SolutionViewer (next section) starts |
(After V14: the next start of any model uses the stored background color - confirmed at S1. Delete the file again at the end.)
4. SolutionViewer and PlotSensor (7 min)
The model continues with mbs.SolutionViewer() automatically.
ID |
action |
expected |
|---|---|---|
S1 |
look at the renderer and the dialog |
renderer reopens with the previous view and the background color stored in V14; dialog with sliders Solution steps, Increment, update period, run modes, record, Make mp4 |
S2 |
let it run; then Static; drag the Solution steps slider |
animation plays; in static mode the model follows the slider |
S3 |
Increment to 10; update period to max |
animation faster (skips frames) / slower |
S4 |
One cycle, Run |
plays once and stops |
S5 |
keys in the render window during the viewer ( |
still work; |
S6 |
Record frames, run one cycle, No recording |
images |
S7 |
close the dialog (window close button, or |
dialog and renderer close, script continues |
P1 |
PlotSensor windows |
two matplotlib figures: tip position x/y/z with legend and axis labels, and the spring force; windows can be zoomed, panned and closed; the script ends after closing them |
5. AnimateModes (5 min)
python nMassOscillatorEigenmodes.py
ID |
action |
expected |
|---|---|---|
A1 |
dialog and renderer open |
dialog with Mode shape, Contour plot, Amplitude (+ positive/negative), update period, run modes, mesh/faces, recording; renderer shows the masses |
A2 |
Run; move the Mode shape slider; move Amplitude; switch negative |
mode animates; the mode changes; amplitude grows/shrinks; motion inverts |
A3 |
Contour plot = Displacement; Static continuous |
each mass in one color (it only translates), the colors differ between the masses, with a color bar; the deformed shape stands still |
A4 |
close the dialog with |
dialog and renderer close, script ends without error or hang |
6. Quitting (3 min)
ID |
action |
expected |
|---|---|---|
Q1 |
|
dialog WARNING - long running simulation! in front; No keeps running; ESCAPE again, Yes stops the solver and closes the window; the script continues (SolutionViewer) or ends without hanging |
Q2 |
in the SolutionViewer of the same run: close the render window with the window close button |
viewer stops, no hang, no crash of the Python process |
7. Optional, if time is left
ID |
action |
expected |
|---|---|---|
O1 |
|
the dialogs without a model; closing vis prints the changed settings as code |
O2 |
3D mouse / 6-axis joystick (3Dconnexion) connected before the renderer starts |
message found 6-axis joystick …; the device moves and rotates the view ( |
O3 |
|
drag the chain with the mouse; F2 / key user function works |
O4 |
|
results monitor opens and updates |
O5 |
display scaling 150-200 % (Windows) / HiDPI (Ubuntu, macOS Retina) |
texts in the render window and the dialogs readable and not blurred; adjust |
8. Finish
Delete
~/.exudyn/config.jsonand restore your backup.Send the report:
python -m exudyn infooutput, platform (OS version, X11/Wayland on Ubuntu, Intel/ARM on macOS, display scaling), the list of IDs with OK / FAIL / n.a., and screenshots of anything that looked wrong.
Platform notes
macOS always renders single-threaded: dialogs run inside the renderer’s idle loop, so the render window does not update while a dialog is open - that is expected. There is no keypad on most keyboards: R9 is n.a., use SHIFT+cursor (R8). CTRL means the control key, not CMD.
Ubuntu: note whether the session is X11 or Wayland. tkinter dialogs may open behind the render window (D2, V1) - note it, it is known; a dialog that cannot be brought to front at all is a FAIL.
Windows: check at least once with display scaling > 100 % (O5), because DPI awareness is set differently with and without the render window (#2634).