| 1 | # A Linux desktop the Computer Use server can be qualified against. |
| 2 | # |
| 3 | # The X11 backend shells out to xdotool/wmctrl/scrot/xclip and reads the |
| 4 | # accessibility tree through AT-SPI (python3 + pyatspi over the session bus), |
| 5 | # and the parity suite needs its two fixtures: a Chrome --app page and a Tk |
| 6 | # window. This image supplies all of that plus Xvfb and a window manager, so |
| 7 | # `npm run parity -- --isolated` reproduces here with nothing installed on the |
| 8 | # host but Docker. |
| 9 | # |
| 10 | # It is a headless X11 session in a container: it qualifies the X11 code paths |
| 11 | # and the isolated parity route. It is not evidence for Wayland, for a real |
| 12 | # login session's window manager (see the KWin modal-dialog row in |
| 13 | # docs/LIMITATIONS.md), or for anything the native macOS app holds. |
| 14 | FROM node:24-bookworm-slim |
| 15 | |
| 16 | ENV DEBIAN_FRONTEND=noninteractive |
| 17 | RUN apt-get update && apt-get install -y --no-install-recommends \ |
| 18 | xvfb openbox x11-utils x11-xserver-utils xauth \ |
| 19 | xdotool wmctrl scrot xclip xsel \ |
| 20 | dbus-x11 at-spi2-core python3-pyatspi python3-gi gir1.2-gtk-3.0 \ |
| 21 | python3-tk \ |
| 22 | chromium fonts-dejavu-core ffmpeg \ |
| 23 | ca-certificates procps git \ |
| 24 | && rm -rf /var/lib/apt/lists/* |
| 25 | |
| 26 | # Chromium's own sandbox needs privileges this container does not have. Debian's |
| 27 | # launcher sources /etc/chromium.d/*, so the flags apply without the parity |
| 28 | # driver knowing it is in a container. |
| 29 | RUN printf '%s\n' \ |
| 30 | 'export CHROMIUM_FLAGS="$CHROMIUM_FLAGS --no-sandbox --disable-dev-shm-usage --disable-gpu"' \ |
| 31 | > /etc/chromium.d/00-container |
| 32 | |
| 33 | # Toolkits load the AT-SPI bridge unless told not to; say so explicitly rather |
| 34 | # than relying on the default. |
| 35 | # xdotool refuses to type non-ASCII text under the C locale ("Invalid |
| 36 | # multi-byte sequence"), which is most of what the unicode tasks exist to check. |
| 37 | ENV LANG=C.UTF-8 \ |
| 38 | LC_ALL=C.UTF-8 |
| 39 | |
| 40 | ENV NO_AT_BRIDGE=0 \ |
| 41 | QT_ACCESSIBILITY=1 \ |
| 42 | GTK_A11Y=atspi \ |
| 43 | XDG_SESSION_TYPE=x11 \ |
| 44 | CODEWHALE_CU_APP=off |
| 45 | |
| 46 | WORKDIR /app |
| 47 | RUN chown node:node /app |
| 48 | USER node |
| 49 | |
| 50 | # Dependencies first so source edits do not re-resolve the tree. There are no |
| 51 | # runtime dependencies; this installs sharp for the icon scripts only. |
| 52 | COPY --chown=node:node package.json package-lock.json ./ |
| 53 | RUN npm ci --ignore-scripts |
| 54 | |
| 55 | COPY --chown=node:node . . |
| 56 | |
| 57 | ENTRYPOINT ["/bin/sh", "/app/docker/entrypoint.sh"] |
| 58 | CMD ["npm", "test"] |
| 59 |