Skip to content

Wait for OctoPrint Setup Wizard before taking screenshot #2222

Wait for OctoPrint Setup Wizard before taking screenshot

Wait for OctoPrint Setup Wizard before taking screenshot #2222

Workflow file for this run

name: Build Image
on:
repository_dispatch:
push:
schedule:
- cron: '0 0 * * *'
jobs:
build:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- board: raspberrypiarmhf
arch: armhf
- board: raspberrypiarm64
arch: arm64
steps:
- name: Install Dependencies
run: |
sudo apt-get update
sudo apt-get install -y coreutils p7zip-full qemu-user-static \
python3-git python3-yaml
- name: Checkout CustomPiOS
uses: actions/checkout@v4
with:
repository: 'guysoft/CustomPiOS'
path: CustomPiOS
- name: Checkout Project Repository
uses: actions/checkout@v4
with:
path: repository
submodules: true
- name: Update CustomPiOS Paths
run: |
cd repository/src
../../CustomPiOS/src/update-custompios-paths
- name: Download Base Image
run: |
cd repository/src
export DIST_PATH=$(pwd)
export CUSTOM_PI_OS_PATH=$(cat custompios_path)
export BASE_BOARD=${{ matrix.board }}
$CUSTOM_PI_OS_PATH/base_image_downloader_wrapper.sh
- name: Build Image
run: |
sudo modprobe loop
cd repository/src
sudo BASE_BOARD=${{ matrix.board }} bash -x ./build_dist
- name: Copy output
id: copy
run: |
source repository/src/config
NOW=$(date +"%Y-%m-%d-%H%M")
IMAGE="${NOW}-octopi-${DIST_VERSION}-${{ matrix.arch }}"
cp repository/src/workspace/*.img ${IMAGE}.img
echo "image=${IMAGE}" >> $GITHUB_OUTPUT
- uses: actions/upload-artifact@v4
with:
name: octopi-${{ matrix.arch }}
path: ${{ steps.copy.outputs.image }}.img
e2e-test:
needs: build
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- name: Download arm64 image from build
uses: actions/download-artifact@v4
with:
name: octopi-arm64
path: image/
- name: Build test Docker image
run: DOCKER_BUILDKIT=0 docker build -t octopi-e2e-test ./testing/
- name: Start E2E test container
run: |
mkdir -p artifacts
IMG=$(find image/ -name '*.img' | head -1)
docker run -d --name octopi-test \
-p 9980:9980 \
-v "$PWD/artifacts:/output" \
-v "$(realpath $IMG):/input/image.img:ro" \
-e ARTIFACTS_DIR=/output \
-e KEEP_ALIVE=true \
octopi-e2e-test
- name: Wait for tests to complete
run: |
for i in $(seq 1 180); do
[ -f artifacts/exit-code ] && break
sleep 5
done
if [ ! -f artifacts/exit-code ]; then
echo "ERROR: Tests did not complete within 15 minutes"
docker logs octopi-test 2>&1 | tail -80
exit 1
fi
echo "Tests finished with exit code: $(cat artifacts/exit-code)"
cat artifacts/test-results.txt 2>/dev/null || true
- name: Wait for OctoPrint to fully start
run: |
echo "Waiting for OctoPrint to finish startup..."
for i in $(seq 1 90); do
BODY=$(curl -4 -s --connect-timeout 5 http://127.0.0.1:9980 2>/dev/null || true)
if echo "$BODY" | grep -q "CONFIG_WIZARD"; then
echo "OctoPrint fully started (Setup Wizard ready)"
exit 0
elif echo "$BODY" | grep -q "starting up"; then
printf "S"
else
printf "."
fi
sleep 5
done
echo ""
echo "WARNING: OctoPrint may not be fully started yet, proceeding anyway"
- name: Take OctoPrint screenshot
run: |
npm install puppeteer
node -e "
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({
headless: 'new', args: ['--no-sandbox']
});
const page = await browser.newPage();
await page.setViewport({width: 1280, height: 900});
// Retry loading until OctoPrint finishes its startup phase
for (let attempt = 0; attempt < 30; attempt++) {
await page.goto('http://127.0.0.1:9980', {
waitUntil: 'networkidle2', timeout: 60000
});
const html = await page.content();
if (html.includes('CONFIG_WIZARD') || html.includes('id=\"login\"')) break;
console.log('OctoPrint still starting up, retrying in 10s... (attempt ' + (attempt+1) + ')');
await new Promise(r => setTimeout(r, 10000));
}
// Wait for the Setup Wizard dialog to appear
try {
await page.waitForSelector('#wizard_dialog', { visible: true, timeout: 120000 });
} catch (e) {
console.log('Wizard did not appear, taking screenshot of current state');
}
// Dismiss notification popovers by clicking the wizard body
try { await page.click('#wizard_dialog .modal-body'); } catch(e) {}
await new Promise(r => setTimeout(r, 2000));
await page.screenshot({path: 'artifacts/octoprint-screenshot.png'});
console.log('Screenshot captured');
await browser.close();
})();
"
- name: Collect logs and stop container
if: always()
run: |
docker logs octopi-test > artifacts/container.log 2>&1 || true
docker stop octopi-test 2>/dev/null || true
- name: Check test result
run: exit "$(cat artifacts/exit-code 2>/dev/null || echo 1)"
- uses: actions/upload-artifact@v4
if: always()
with:
name: e2e-test-results
path: artifacts/