Skip to content

Commit 08b4296

Browse files
authored
Add comprehensive E2E test framework with Playwright (#275)
1 parent 7b9d301 commit 08b4296

29 files changed

+3383
-13
lines changed

.github/workflows/e2e.yml

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
name: Scalable RTR E2E Tests
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
pull_request:
7+
branches: [ main ]
8+
workflow_dispatch:
9+
10+
# Serialize E2E tests to prevent deployment and UI collisions
11+
concurrency:
12+
group: e2e-tests-${{ github.repository }}
13+
cancel-in-progress: false # Let running tests finish before starting new ones
14+
15+
permissions:
16+
contents: read
17+
18+
jobs:
19+
e2e:
20+
runs-on: ubuntu-latest
21+
timeout-minutes: 15
22+
if: github.actor != 'dependabot[bot]'
23+
env:
24+
FOUNDRY_API_CLIENT_ID: ${{ secrets.FOUNDRY_API_CLIENT_ID }}
25+
FOUNDRY_API_CLIENT_SECRET: ${{ secrets.FOUNDRY_API_CLIENT_SECRET }}
26+
FOUNDRY_CID: ${{ secrets.FOUNDRY_CID }}
27+
FOUNDRY_CLOUD_REGION: ${{ secrets.FOUNDRY_CLOUD_REGION }}
28+
steps:
29+
- name: Harden Runner
30+
uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.13.2
31+
with:
32+
egress-policy: audit
33+
34+
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
35+
36+
- name: Set up Homebrew
37+
uses: Homebrew/actions/setup-homebrew@1ccc07ccd8b9519f44d3e5eaa1b41dd90310adf0 # 2024-10-25
38+
39+
- name: Install required tools
40+
run: |
41+
brew tap crowdstrike/foundry-cli
42+
brew install crowdstrike/foundry-cli/foundry yq
43+
44+
- name: Create directory for Foundry CLI
45+
run: mkdir -p ~/.config/foundry
46+
47+
- name: Prepare app manifest
48+
run: |
49+
# Remove IDs from manifest
50+
yq -i 'del(.. | select(has("id")).id) | del(.. | select(has("app_id")).app_id)' manifest.yml
51+
52+
# Generate unique app name with length safety
53+
REPO_NAME="${{ github.event.repository.name }}"
54+
ACTOR="${{ github.actor }}"
55+
SHORT_ACTOR="${ACTOR/dependabot\[bot\]/deps}"
56+
UNIQUE_NAME="${REPO_NAME}-${SHORT_ACTOR}-$(date +"%m%d%H%M")"
57+
58+
# Truncate if too long by removing foundry- prefix
59+
if [ ${#UNIQUE_NAME} -gt 50 ]; then
60+
REPO_BASE="${REPO_NAME#foundry-}"
61+
UNIQUE_NAME="${REPO_BASE}-${SHORT_ACTOR}-$(date +"%m%d%H%M")"
62+
fi
63+
64+
# Export for yq and set the manifest name
65+
export UNIQUE_NAME
66+
yq -i '.name = env(UNIQUE_NAME)' manifest.yml
67+
68+
# Set app name as environment variable
69+
APP_NAME=$(yq '.name' manifest.yml)
70+
echo "APP_NAME=$APP_NAME" >> $GITHUB_ENV
71+
72+
echo "Prepared manifest with app name: $APP_NAME"
73+
74+
- name: Deploy app to Falcon
75+
run: |
76+
foundry apps deploy --change-type=major --change-log="e2e deploy"
77+
echo "App deployment initiated"
78+
79+
- name: Wait for deployment and release app
80+
run: |
81+
echo "Waiting for deployment to complete..."
82+
timeout=300 # 5 minute timeout
83+
elapsed=0
84+
85+
while [ $elapsed -lt $timeout ]; do
86+
if foundry apps list-deployments | grep -i "successful"; then
87+
echo "Deployment successful, releasing app..."
88+
foundry apps release --change-type=major --notes="e2e release"
89+
echo "App released successfully"
90+
91+
# Brief wait for release to complete - E2E tests handle app discovery with retries
92+
echo "Allowing brief time for release to complete..."
93+
sleep 15
94+
95+
# Verify deployment status and get app details
96+
echo "Verifying final deployment status..."
97+
foundry apps list-deployments
98+
99+
echo "Final deployed app name: $APP_NAME"
100+
101+
exit 0
102+
fi
103+
104+
if foundry apps list-deployments | grep -i "failed"; then
105+
echo "Deployment failed"
106+
exit 1
107+
fi
108+
109+
sleep 5
110+
elapsed=$((elapsed + 5))
111+
done
112+
113+
echo "Deployment timeout after ${timeout} seconds"
114+
exit 1
115+
116+
# Parallelize Node setup while deployment happens
117+
- name: Install Node LTS
118+
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
119+
with:
120+
node-version: 22
121+
cache: 'npm'
122+
cache-dependency-path: e2e/package-lock.json
123+
124+
- name: Install dependencies
125+
run: npm ci
126+
working-directory: e2e
127+
128+
- name: Install Playwright browsers
129+
run: npx playwright install chromium --with-deps
130+
working-directory: e2e
131+
132+
- name: Make envfile
133+
uses: SpicyPizza/create-envfile@6da099c0b655bd3abd8273c4e2fe7c59e63fa88a # v2.0.3
134+
with:
135+
envkey_FALCON_USERNAME: ${{ secrets.FALCON_USERNAME }}
136+
envkey_FALCON_PASSWORD: ${{ secrets.FALCON_PASSWORD }}
137+
envkey_FALCON_AUTH_SECRET: ${{ secrets.FALCON_AUTH_SECRET }}
138+
envkey_APP_NAME: $APP_NAME
139+
directory: e2e
140+
141+
- name: Run Playwright tests
142+
run: npx dotenvx run --quiet -- npx playwright test
143+
working-directory: e2e
144+
env:
145+
CI: true
146+
147+
- name: Upload Playwright report
148+
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
149+
if: ${{ !cancelled() }}
150+
with:
151+
name: playwright-report-${{ env.APP_NAME }}
152+
path: e2e/playwright-report/
153+
retention-days: 7
154+
155+
- name: Upload test results and screenshots
156+
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
157+
if: ${{ !cancelled() }}
158+
with:
159+
name: playwright-test-results-${{ env.APP_NAME }}
160+
path: e2e/test-results/
161+
retention-days: 7
162+
163+
- name: Delete app from Falcon
164+
if: always()
165+
run: |
166+
echo "Deleting app: $APP_NAME"
167+
foundry apps delete -f || echo "App deletion failed, may already be deleted"

.github/workflows/main.yml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ jobs:
1414
with:
1515
egress-policy: audit
1616

17-
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
17+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v5.0.0
1818
- name: Setup Go
19-
uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6
19+
uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v6.0.0
2020
with:
2121
go-version: '1.23.x'
2222
- name: Install Go dependencies
@@ -30,23 +30,23 @@ jobs:
3030
go build -C functions/Func_Jobs
3131
go build -C functions/job_history
3232
- name: Use Node 22
33-
uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6
33+
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v6.0.0
3434
with:
3535
node-version: 22
3636
cache: 'yarn'
3737
cache-dependency-path: ui/pages/scalable-rtr-react/yarn.lock
3838
- name: Run yarn install
39-
uses: borales/actions-yarn@2a18ac083c150a32c8ae27a3d68fc8f77b2ad4be # v5
39+
uses: borales/actions-yarn@2a18ac083c150a32c8ae27a3d68fc8f77b2ad4be # v5.3.0
4040
with:
4141
cmd: install
4242
dir: ui/pages/scalable-rtr-react
4343
- name: Build React app
44-
uses: borales/actions-yarn@2a18ac083c150a32c8ae27a3d68fc8f77b2ad4be # v5
44+
uses: borales/actions-yarn@2a18ac083c150a32c8ae27a3d68fc8f77b2ad4be # v5.3.0
4545
with:
4646
cmd: build
4747
dir: ui/pages/scalable-rtr-react
4848
- name: Test the React app
49-
uses: borales/actions-yarn@2a18ac083c150a32c8ae27a3d68fc8f77b2ad4be # v5
49+
uses: borales/actions-yarn@2a18ac083c150a32c8ae27a3d68fc8f77b2ad4be # v5.3.0
5050
with:
5151
cmd: test
5252
dir: ui/pages/scalable-rtr-react

.github/workflows/rebuild.yml

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,26 +16,24 @@ jobs:
1616
if: github.repository == 'CrowdStrike/foundry-sample-scalable-rtr'
1717
runs-on: ubuntu-latest
1818
steps:
19-
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
20-
- uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6
2119
- name: Harden Runner
2220
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
2321
with:
2422
egress-policy: audit
2523

26-
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
27-
- uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6
24+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v5.0.0
25+
- uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v6.0.0
2826
with:
2927
node-version: 22
3028
cache: 'yarn'
3129
cache-dependency-path: ui/pages/scalable-rtr-react/yarn.lock
3230
- name: Run yarn install
33-
uses: borales/actions-yarn@2a18ac083c150a32c8ae27a3d68fc8f77b2ad4be # v5
31+
uses: borales/actions-yarn@2a18ac083c150a32c8ae27a3d68fc8f77b2ad4be # v5.3.0
3432
with:
3533
cmd: install
3634
dir: ui/pages/scalable-rtr-react
3735
- name: Build React app
38-
uses: borales/actions-yarn@2a18ac083c150a32c8ae27a3d68fc8f77b2ad4be # v5
36+
uses: borales/actions-yarn@2a18ac083c150a32c8ae27a3d68fc8f77b2ad4be # v5.3.0
3937
with:
4038
cmd: build
4139
dir: ui/pages/scalable-rtr-react
@@ -44,7 +42,7 @@ jobs:
4442
git add .
4543
git commit -a -m "Rebuild with latest dependencies" || true
4644
- name: Create Pull Request
47-
uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7
45+
uses: peter-evans/create-pull-request@5e914681df9dc83aa4e4905692ca88beb2f9e91f # v7.0.5
4846
with:
4947
token: ${{ secrets.GITHUB_TOKEN }}
5048
commit-message: 'Rebuild with latest dependencies'

e2e/.env.sample

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
APP_NAME=foundry-sample-scalable-rtr
2+
FALCON_BASE_URL=https://falcon.us-2.crowdstrike.com
3+
FALCON_USERNAME=your-falcon-username
4+
FALCON_PASSWORD=your-falcon-password
5+
FALCON_AUTH_SECRET=your-mfa-secret

e2e/.gitignore

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Environment variables
2+
.env
3+
.env.local
4+
.env.keys
5+
6+
# Playwright
7+
/test-results/
8+
/playwright-report/
9+
/playwright/.cache/
10+
/playwright/.auth/
11+
12+
# Dependencies
13+
node_modules/
14+
15+
# Test artifacts
16+
*.png
17+
*.jpg
18+
*.mp4
19+
*.webm
20+
*.log

e2e/README.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# E2E Tests
2+
3+
## Setup
4+
5+
```bash
6+
npm ci
7+
npx playwright install chromium
8+
cp .env.sample .env
9+
# Edit .env with your credentials
10+
```
11+
12+
## Run Tests
13+
14+
```bash
15+
npm test # All tests
16+
npm run test:debug # Debug mode
17+
npm run test:ui # Interactive UI
18+
```
19+
20+
## Environment Variables
21+
22+
```env
23+
APP_NAME=foundry-sample-scalable-rtr
24+
FALCON_BASE_URL=https://falcon.us-2.crowdstrike.com
25+
FALCON_USERNAME=your-username
26+
FALCON_PASSWORD=your-password
27+
FALCON_AUTH_SECRET=your-mfa-secret
28+
```

e2e/constants/AuthFile.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export const AUTH_FILE = 'playwright/.auth/user.json';

0 commit comments

Comments
 (0)