Skip to content

Commit 5644188

Browse files
author
greweb
committed
fix: CI to export artifacts and fail on mismatch
1 parent f13c3db commit 5644188

14 files changed

+8144
-7967
lines changed

.github/workflows/ci.yml

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -549,11 +549,12 @@ jobs:
549549
550550
- name: Run Detox Tests
551551
working-directory: example
552-
run: npm run test:e2e:ios || true
552+
run: npm run test:e2e:ios
553+
continue-on-error: true
553554
id: detox_ios_tests
554555

555556
- name: Check for iOS snapshot differences
556-
if: always()
557+
if: failure() && steps.detox_ios_tests.outcome == 'failure'
557558
working-directory: example
558559
run: |
559560
if [ -d "e2e/snapshots/output" ] && [ "$(ls -A e2e/snapshots/output 2>/dev/null)" ]; then
@@ -603,6 +604,12 @@ jobs:
603604
example/e2e/test-results/**/*
604605
example/artifacts/**/*.xml
605606
607+
- name: Fail CI if iOS tests failed
608+
if: steps.detox_ios_tests.outcome == 'failure'
609+
run: |
610+
echo "❌ iOS Detox tests failed - failing CI"
611+
exit 1
612+
606613
test-detox-android:
607614
name: Detox E2E Tests (Android)
608615
runs-on: ubuntu-latest
@@ -680,15 +687,16 @@ jobs:
680687
681688
- name: Create AVD and run Detox tests
682689
uses: reactivecircus/android-emulator-runner@v2
690+
id: detox_android_tests
683691
with:
684-
api-level: 28
692+
api-level: 29
685693
target: google_apis
686694
arch: x86_64
687-
profile: pixel_3a
688-
force-avd-creation: false
689-
emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none -no-snapshot-save -no-snapshot-load -memory 768 -cores 1 -qemu -enable-kvm -no-snapshot -wipe-data
695+
profile: Nexus_6
696+
force-avd-creation: true
697+
emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none -memory 512 -cores 1 -qemu -enable-kvm -no-snapshot -wipe-data
690698
disable-animations: true
691-
emulator-boot-timeout: 900
699+
emulator-boot-timeout: 1800
692700
script: |
693701
cd example
694702
echo "🚀 Starting Metro bundler..."
@@ -747,6 +755,12 @@ jobs:
747755
example/e2e/test-results/**/*
748756
example/artifacts/**/*.xml
749757
758+
- name: Fail CI if Android tests failed
759+
if: steps.detox_android_tests.outcome == 'failure'
760+
run: |
761+
echo "❌ Android Detox tests failed - failing CI"
762+
exit 1
763+
750764
build-web-example:
751765
name: Build Web Example
752766
runs-on: ubuntu-latest
@@ -865,12 +879,12 @@ jobs:
865879
done
866880
fi
867881
868-
- name: Upload reference snapshots (for updates)
882+
- name: Upload generated snapshots (for updates)
869883
if: always()
870884
uses: actions/upload-artifact@v4
871885
with:
872-
name: web-snapshots-reference
873-
path: example-web/e2e/snapshots/reference/
886+
name: web-snapshots-generated
887+
path: example-web/e2e/snapshots/output/
874888
retention-days: 30
875889

876890
- name: Upload snapshot diffs (if any)
Binary file not shown.
Binary file not shown.
14.1 KB
Loading
20.6 KB
Loading

example-web/e2e/viewshot.spec.ts

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,4 +147,66 @@ test.describe("ViewShot Web Example", () => {
147147
// Verify download button appears
148148
await expect(page.locator("text=⬇️ Download Image")).toBeVisible();
149149
});
150+
151+
test("should capture ImageTestScreen with real images", async ({page}) => {
152+
await page.goto("/");
153+
await page.click("text=Image Capture");
154+
155+
// Wait for page to be ready
156+
await page.waitForSelector("text=🖼️ Image Gallery");
157+
158+
// Wait for all images to load and be visible
159+
await page.waitForLoadState("networkidle");
160+
161+
// Wait for any images to be loaded (more flexible selector)
162+
await page.waitForSelector('img[src*="test-image"]', {timeout: 10000});
163+
164+
// Additional wait to ensure images are fully rendered
165+
await page.waitForTimeout(5000);
166+
167+
// Click PNG capture button
168+
await page.click("text=📸 Capture as PNG");
169+
170+
// Wait for capture to complete
171+
await page.waitForSelector("text=✅ Captured Result:", {timeout: 10000});
172+
173+
// Verify preview image appears
174+
const previewImage = page.locator('img[src^="data:image/png"]');
175+
await expect(previewImage).toBeVisible();
176+
177+
// Visual snapshot of the captured image with real images (high resolution)
178+
await expect(previewImage).toHaveScreenshot(
179+
"image-test-screen-capture.png",
180+
{
181+
threshold: 0.2,
182+
maxDiffPixels: 1000,
183+
// Increase snapshot resolution
184+
scale: "css",
185+
animations: "disabled",
186+
},
187+
);
188+
});
189+
190+
test("should capture ComplexLayoutScreen", async ({page}) => {
191+
await page.goto("/");
192+
await page.click("text=Complex Layout");
193+
194+
// Wait for page to be ready
195+
await page.waitForSelector("text=Complex Layout Test");
196+
197+
// Click PNG capture button
198+
await page.click("text=📸 Capture This Layout");
199+
200+
// Wait for capture to complete
201+
await page.waitForSelector("text=✅ Captured Successfully!", {
202+
timeout: 10000,
203+
});
204+
205+
// Verify preview image appears
206+
const previewImage = page.locator('img[src^="data:image/png"]');
207+
await expect(previewImage).toBeVisible();
208+
209+
// Visual snapshot of the complex layout
210+
await expect(previewImage).toHaveScreenshot("complex-layout-capture.png");
211+
});
150212
});

0 commit comments

Comments
 (0)