Skip to content

Commit 4d768aa

Browse files
authored
E2E test: use docker image (#8694)
Add docker images to CI workflow for Ubuntu. This decreases the average test execution time by 5-10 minutes. Dockerfiles are at [Positron CI Images](https://github.com/posit-dev/positron-ci-images). This repo is private so authentication is required. Note that integration tests now also use a container, but unit tests do not yet. In docker, the tests run as root, as required according to [Github Documentation](https://docs.github.com/en/actions/reference/workflows-and-actions/dockerfile-support). This has necessitated some changes: * python interpreters now must be on the include list. This is accomplished by having a separate settingsDocker.json file which is merged with settings.json for docker runs. * some tests now have different "expected" or configuration paths. ### QA Notes @:web @:connections @:quarto @:test-explorer
1 parent 6fd6131 commit 4d768aa

26 files changed

+227
-179
lines changed

.github/actions/setup-build-env/action.yml

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -3,39 +3,13 @@ description: "Installs necessary system dependencies."
33
runs:
44
using: "composite"
55
steps:
6-
- name: Install Build Dependencies
7-
shell: bash
8-
run: |
9-
# Detect Ubuntu version
10-
UBUNTU_VERSION=$(lsb_release -rs)
11-
echo "Running on Ubuntu version: $UBUNTU_VERSION"
12-
13-
# Install libasound2 or libasound2t64 based on version
14-
if [[ "$UBUNTU_VERSION" == "24.04" ]]; then
15-
echo "Installing libasound2t64 for Ubuntu 24.04"
16-
sudo apt-get update
17-
sudo apt-get install -y libasound2t64
18-
else
19-
echo "Installing libasound2 for older Ubuntu versions"
20-
sudo apt-get update
21-
sudo apt-get install -y libasound2
22-
fi
23-
sudo apt-get install -y \
24-
vim curl build-essential clang make cmake git \
25-
libsodium-dev libxkbfile-dev pkg-config libsecret-1-dev libxss1 dbus xvfb \
26-
libgtk-3-0 libgbm1 libnss3 libnspr4 libkrb5-dev libcairo-dev \
27-
libsdl-pango-dev libjpeg-dev libgif-dev pandoc libgtk-4-1
28-
296
- name: Install Node packages
307
shell: bash
318
env:
329
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1
3310
ELECTRON_SKIP_BINARY_DOWNLOAD: 1
3411
POSITRON_GITHUB_PAT: ${{ github.token }}
3512
run: |
36-
# Install node-gyp; this is required by some packages
37-
npm i --global node-gyp
38-
3913
# Perform the main npm command; this installs all Node packages and
4014
# dependencies
4115
npm ci --fetch-timeout 120000
@@ -53,15 +27,6 @@ runs:
5327
sudo chmod 4755 $ELECTRON_ROOT/chrome-sandbox
5428
stat $ELECTRON_ROOT/chrome-sandbox
5529
56-
# Although not directly part of the build environment, this configuration is essential for running unit, integration, and e2e tests.
57-
- name: Configure xvfb Service
58-
shell: bash
59-
run: |
60-
sudo cp build/azure-pipelines/linux/xvfb.init /etc/init.d/xvfb
61-
sudo chmod +x /etc/init.d/xvfb
62-
sudo update-rc.d xvfb defaults
63-
sudo service xvfb start
64-
6530
# Downloads Builtin Extensions (needed for integration & e2e testing)
6631
- shell: bash
6732
run: npm run prelaunch

.github/actions/setup-test-env/action.yml

Lines changed: 3 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,7 @@ inputs:
77
aws-region:
88
description: "The AWS region for S3"
99
required: true
10-
github-token:
11-
description: "GitHub Token for accessing private repositories or APIs"
12-
required: true
13-
install_undetectable_interpreters:
14-
description: "Install undetectable interpreters"
15-
required: true
10+
1611
runs:
1712
using: "composite"
1813
steps:
@@ -26,35 +21,5 @@ runs:
2621
role-to-assume: ${{ inputs.aws-role-to-assume }}
2722
aws-region: ${{ inputs.aws-region }}
2823

29-
- name: Setup Graphviz
30-
uses: ts-graphviz/setup-graphviz@v2.0.2
31-
32-
- name: Setup Quarto
33-
uses: quarto-dev/quarto-actions/setup@v2
34-
env:
35-
GH_TOKEN: ${{ inputs.github-token }}
36-
with:
37-
tinytex: true
38-
39-
# Miniforge avoids Anaconda ToS and defaults to conda-forge
40-
- name: Setup Conda (Miniforge3)
41-
uses: conda-incubator/setup-miniconda@v3
42-
with:
43-
miniforge-version: latest
44-
auto-activate-base: false
45-
channels: conda-forge,defaults # Defaults included only to suppress warnings; all packages are still resolved from conda-forge
46-
conda-remove-defaults: "true"
47-
channel-priority: strict
48-
49-
- name: Setup Python
50-
uses: ./.github/actions/install-python
51-
with:
52-
alternate_version: "3.13.0"
53-
install_undetectable_interpreters: ${{ inputs.install_undetectable_interpreters }}
54-
55-
- name: Setup R
56-
uses: ./.github/actions/install-r
57-
with:
58-
version: "4.4.0"
59-
alternate_version: "4.4.2"
60-
install_undetectable_interpreters: ${{ inputs.install_undetectable_interpreters }}
24+
- name: Setup Xvfb
25+
uses: ./.github/actions/setup-xvfb
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
name: "Setup Build Environment, Install Dependencies, and Compile App"
2+
description: "Installs necessary system dependencies."
3+
runs:
4+
using: "composite"
5+
steps:
6+
- name: Install Build Dependencies
7+
shell: bash
8+
run: |
9+
# Detect Ubuntu version
10+
UBUNTU_VERSION=$(lsb_release -rs)
11+
echo "Running on Ubuntu version: $UBUNTU_VERSION"
12+
13+
# Install libasound2 or libasound2t64 based on version
14+
if [[ "$UBUNTU_VERSION" == "24.04" ]]; then
15+
echo "Installing libasound2t64 for Ubuntu 24.04"
16+
sudo apt-get update
17+
sudo apt-get install -y libasound2t64
18+
else
19+
echo "Installing libasound2 for older Ubuntu versions"
20+
sudo apt-get update
21+
sudo apt-get install -y libasound2
22+
fi
23+
sudo apt-get install -y \
24+
vim curl build-essential clang make cmake git \
25+
libsodium-dev libxkbfile-dev pkg-config libsecret-1-dev libxss1 dbus xvfb \
26+
libgtk-3-0 libgbm1 libnss3 libnspr4 libkrb5-dev libcairo-dev \
27+
libsdl-pango-dev libjpeg-dev libgif-dev pandoc libgtk-4-1
28+
29+
- name: Install Node packages
30+
shell: bash
31+
env:
32+
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1
33+
ELECTRON_SKIP_BINARY_DOWNLOAD: 1
34+
POSITRON_GITHUB_PAT: ${{ github.token }}
35+
run: |
36+
# Install node-gyp; this is required by some packages
37+
npm i --global node-gyp
38+
39+
# Perform the main npm command; this installs all Node packages and
40+
# dependencies
41+
npm ci --fetch-timeout 120000
42+
npm --prefix test/e2e ci
43+
44+
- name: Compile and Download
45+
shell: bash
46+
run: npm exec -- npm-run-all --max_old_space_size=4095 -lp compile "electron x64" playwright-install
47+
48+
- name: Set permissions on SUID sandbox helper
49+
shell: bash
50+
run: |
51+
ELECTRON_ROOT=.build/electron
52+
sudo chown root $ELECTRON_ROOT/chrome-sandbox
53+
sudo chmod 4755 $ELECTRON_ROOT/chrome-sandbox
54+
stat $ELECTRON_ROOT/chrome-sandbox
55+
56+
# Although not directly part of the build environment, this configuration is essential for running unit, integration, and e2e tests.
57+
- name: Configure xvfb Service
58+
shell: bash
59+
run: |
60+
sudo cp build/azure-pipelines/linux/xvfb.init /etc/init.d/xvfb
61+
sudo chmod +x /etc/init.d/xvfb
62+
sudo update-rc.d xvfb defaults
63+
sudo service xvfb start
64+
65+
# Downloads Builtin Extensions (needed for integration & e2e testing)
66+
- shell: bash
67+
run: npm run prelaunch

.github/actions/setup-xvfb/action.yml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
name: "Setup Xvfb"
2+
description: "Configure and start Xvfb virtual framebuffer"
3+
4+
runs:
5+
using: "composite"
6+
steps:
7+
- name: Setup Xvfb
8+
shell: bash
9+
run: |
10+
# Start Xvfb in the background
11+
/usr/bin/Xvfb :10 -ac -screen 0 2560x1440x24 > /tmp/Xvfb.out 2>&1 &
12+
13+
# Wait until Xvfb is ready
14+
export DISPLAY=:10
15+
for i in {1..10}; do
16+
if xdpyinfo > /dev/null 2>&1; then
17+
echo "Xvfb is ready"
18+
break
19+
fi
20+
echo "Waiting for Xvfb to start..."
21+
sleep 1
22+
done
23+
24+
# Export the DISPLAY variable for subsequent steps
25+
echo "DISPLAY=:10" >> $GITHUB_ENV

.github/workflows/test-e2e-ubuntu.yml

Lines changed: 23 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ on:
5757
required: false
5858
description: "Whether or not to upload e2e test logs."
5959
type: boolean
60-
default: false
60+
default: true
6161

6262
workflow_dispatch:
6363
inputs:
@@ -83,15 +83,27 @@ on:
8383
permissions:
8484
id-token: write
8585
contents: read
86+
packages: read
8687

8788
jobs:
89+
8890
e2e-linux:
8991
name: ${{ inputs.display_name || 'e2e-linux' }}
9092
timeout-minutes: 120
9193
runs-on: ubuntu-latest-8x
94+
container:
95+
image: ghcr.io/posit-dev/positron-ubuntu24-amd64:21
96+
options: --user 0:0
97+
# Static PAT is needed because the bot can't pass a token to the job for security reasons
98+
credentials:
99+
username: ${{ secrets.POSITRON_GITHUB_USER }}
100+
password: ${{ secrets.POSITRON_GITHUB_PAT }}
92101
services:
93102
postgres:
94-
image: postgres:latest
103+
image: ghcr.io/posit-dev/positron-postgres-initialized:21
104+
credentials:
105+
username: ${{ secrets.POSITRON_GITHUB_USER }}
106+
password: ${{ secrets.POSITRON_GITHUB_PAT }}
95107
ports:
96108
- 5432:5432
97109
env:
@@ -111,6 +123,8 @@ jobs:
111123
E2E_POSTGRES_DB: ${{ secrets.E2E_POSTGRES_DB }}
112124
E2E_CONNECT_SERVER: ${{ secrets.E2E_CONNECT_SERVER}}
113125
E2E_CONNECT_APIKEY: ${{ secrets.E2E_CONNECT_APIKEY}}
126+
R_LIBS_SITE: /usr/local/lib/R/site-library
127+
R_LIBS_USER: /usr/local/lib/R/site-library
114128
steps:
115129
- uses: actions/checkout@v4
116130

@@ -123,31 +137,10 @@ jobs:
123137
OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }}
124138
ANTHROPIC_API_KEY: "op://Positron/Anthropic/credential"
125139

126-
- uses: actions/setup-node@v4
127-
with:
128-
node-version-file: .nvmrc
129-
130-
- name: Download sample database
131-
run: |
132-
wget https://raw.githubusercontent.com/neondatabase/postgres-sample-dbs/main/periodic_table.sql
133-
134-
- name: Connect to PostgreSQL and load sample data
135-
env:
136-
PGHOST: localhost
137-
PGPORT: 5432
138-
PGUSER: ${{ secrets.E2E_POSTGRES_USER }}
139-
PGPASSWORD: ${{ secrets.E2E_POSTGRES_PASSWORD }}
140-
PGDATABASE: ${{ secrets.E2E_POSTGRES_DB }}
141-
run: |
142-
psql -v ON_ERROR_STOP=1 -f periodic_table.sql
143-
144140
- name: Transform to Playwright tags $PW_TAGS
145141
run: bash scripts/pr-tags-transform.sh ${{ inputs.project}} "${{ inputs.grep }}"
146142
shell: bash
147143

148-
- name: Cache node_modules, build, extensions, and remote
149-
uses: ./.github/actions/cache-multi-paths
150-
151144
- name: Attempt 1 - Setup Build and Compile
152145
id: attempt1
153146
uses: ./.github/actions/setup-build-env
@@ -180,8 +173,6 @@ jobs:
180173
with:
181174
aws-role-to-assume: ${{ secrets.QA_AWS_RO_ROLE }}
182175
aws-region: ${{ secrets.QA_AWS_REGION }}
183-
github-token: ${{ secrets.GITHUB_TOKEN }}
184-
install_undetectable_interpreters: ${{ inputs.install_undetectable_interpreters }}
185176

186177
# Preloading ensures the Node.js binary is fully built and ready before
187178
# any parallel processes start, preventing runtime conflicts
@@ -196,10 +187,11 @@ jobs:
196187
run: sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0
197188

198189
- name: Run Playwright Tests (Electron)
190+
shell: bash
199191
env:
200-
POSITRON_PY_VER_SEL: 3.12.6
192+
POSITRON_PY_VER_SEL: "3.12.11 (Venv: .venv)"
201193
POSITRON_R_VER_SEL: 4.4.0
202-
POSITRON_PY_ALT_VER_SEL: "3.13.0 (Pyenv)"
194+
POSITRON_PY_ALT_VER_SEL: "3.13.0"
203195
POSITRON_R_ALT_VER_SEL: 4.4.2
204196
POSITRON_HIDDEN_PY: "3.12.10 (Conda)"
205197
POSITRON_HIDDEN_R: 4.4.1
@@ -249,12 +241,12 @@ jobs:
249241
echo "Final --grep-invert argument: $GREP_INVERT_ARG"
250242
251243
# Don't run this test in parallel & don't allow skipping it
252-
echo "Running: DISPLAY=:10 npx playwright test test/e2e/tests/extensions/bootstrap-extensions.test.ts --project ${{ inputs.project }} --reporter=null"
253-
DISPLAY=:10 npx playwright test test/e2e/tests/extensions/bootstrap-extensions.test.ts --project ${{ inputs.project }} --reporter=null
244+
echo "Running: npx playwright test test/e2e/tests/extensions/bootstrap-extensions.test.ts --project ${{ inputs.project }} --reporter=null"
245+
npx playwright test test/e2e/tests/extensions/bootstrap-extensions.test.ts --project ${{ inputs.project }} --reporter=null
254246
255247
# Run the Playwright test command directly using eval
256-
echo "Running: DISPLAY=:10 npx playwright test --project ${{ inputs.project }} --workers 2 $GREP_ARG $GREP_INVERT_ARG --repeat-each ${{ inputs.repeat_each }} --max-failures 10"
257-
eval DISPLAY=:10 SKIP_BOOTSTRAP=true SKIP_CLONE=true npx playwright test --project ${{ inputs.project }} --workers 2 $GREP_ARG $GREP_INVERT_ARG --repeat-each ${{ inputs.repeat_each }} --max-failures 10
248+
echo "Running: npx playwright test --project ${{ inputs.project }} --workers 2 $GREP_ARG $GREP_INVERT_ARG --repeat-each ${{ inputs.repeat_each }} --max-failures 10"
249+
eval SKIP_BOOTSTRAP=true SKIP_CLONE=true npx playwright test --project ${{ inputs.project }} --workers 2 $GREP_ARG $GREP_INVERT_ARG --repeat-each ${{ inputs.repeat_each }} --max-failures 10
258250
259251
- name: Upload Playwright Report to S3
260252
if: ${{ success() || failure() }}
@@ -263,28 +255,10 @@ jobs:
263255
role-to-assume: ${{ secrets.AWS_TEST_REPORTS_ROLE }}
264256
report-dir: ${{ env.REPORT_DIR }}
265257

266-
- name: Install trcli
267-
if: ${{ inputs.report_testrail }}
268-
shell: bash
269-
run: sudo apt-get update && sudo apt-get install -y python3-pip && pip3 install trcli
270-
271-
- name: Upload Test Results to TestRail
272-
if: ${{ inputs.report_testrail }}
273-
shell: bash
274-
run: |
275-
TESTRAIL_TITLE="$(date +'%Y-%m-%d') ${{ env.TESTRAIL_TITLE }} - $GITHUB_REF_NAME"
276-
echo "TESTRAIL_TITLE=$TESTRAIL_TITLE" >> $GITHUB_ENV
277-
trcli --host "https://posit.testrail.io/" --project "${{ env.TESTRAIL_PROJECT }}" --username testrailautomation@posit.co --key "${{ env.TESTRAIL_API_KEY }}" parse_junit --file "./test-results/junit.xml" --case-matcher name --title "$TESTRAIL_TITLE" --close-run
278-
env:
279-
TESTRAIL_TITLE: ${{ inputs.project }}
280-
TESTRAIL_PROJECT: "Positron"
281-
TESTRAIL_API_KEY: ${{ secrets.TESTRAIL_API_KEY }}
282-
283258
- name: Upload Test Logs
284259
if: ${{ always() && inputs.upload_logs }}
285260
uses: actions/upload-artifact@v4
286261
with:
287262
name: ${{ inputs.project }}-logs
288263
path: test-logs
289264
if-no-files-found: ignore
290-

.github/workflows/test-integration.yml

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@ jobs:
2222
integration-tests:
2323
name: integration
2424
runs-on: ubuntu-latest-4x
25+
container:
26+
image: ghcr.io/posit-dev/positron-ubuntu24-amd64:21
27+
options: --user 0:0
28+
credentials:
29+
username: ${{ secrets.POSITRON_GITHUB_USER }}
30+
password: ${{ secrets.POSITRON_GITHUB_PAT }}
2531
timeout-minutes: 40
2632
env:
2733
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -64,9 +70,8 @@ jobs:
6470
github-token: ${{ secrets.POSITRON_GITHUB_PAT }}
6571
license-key: ${{ secrets.POSITRON_DEV_LICENSE }}
6672

67-
# one integration test needs this: Connections pane works for R
68-
- name: Setup R
69-
uses: ./.github/actions/install-r
73+
- name: Setup XVFB
74+
uses: ./.github/actions/setup-xvfb
7075
with:
7176
version: "4.4.0"
7277

0 commit comments

Comments
 (0)