Skip to content

Commit 495fcfc

Browse files
authored
Merge pull request #134 from github-copilot-resources/playwright-alpine
Playwright tests + switching to alpine images
2 parents 692012c + ff32180 commit 495fcfc

21 files changed

+465
-37
lines changed

.dockerignore

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,14 @@ dist/
1313
.github/
1414
Dockerfile
1515
*.md
16+
azure-deploy/
17+
infra/
18+
19+
/playwright-report/
20+
/blob-report/
21+
/playwright/.cache/
22+
23+
/test-results/
24+
/test-results-docker/
25+
test-results-docker-ent/
26+
test-results-docker-org/

.env

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,7 @@ VUE_APP_GITHUB_TOKEN=
1919

2020
# GitHub Api Url
2121
# for proxy api - set to /api/github defaults to https://api.github.com
22-
VUE_APP_GITHUB_API=
22+
VUE_APP_GITHUB_API=
23+
24+
# Random string used in API to secure session, use when VUE_APP_GITHUB_API=/api/github
25+
#SESSION_SECRET=randomstring
File renamed without changes.

.github/workflows/playwright.yml

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
name: Playwright Tests
2+
on:
3+
push:
4+
branches: [ main, master ]
5+
pull_request:
6+
branches: [ main, master ]
7+
jobs:
8+
test:
9+
timeout-minutes: 10
10+
permissions:
11+
checks: write
12+
pull-requests: read
13+
runs-on: ubuntu-latest
14+
steps:
15+
- uses: actions/checkout@v4
16+
- uses: actions/setup-node@v4
17+
with:
18+
node-version: lts/*
19+
- name: Install dependencies
20+
run: npm ci
21+
- name: Install Playwright Browsers
22+
run: npx playwright install --with-deps
23+
- name: Run Playwright tests
24+
run: CI=true npm test
25+
- uses: actions/upload-artifact@v4
26+
if: ${{ !cancelled() }}
27+
with:
28+
name: playwright-report
29+
path: playwright-report/
30+
retention-days: 30
31+
32+
test-api-org:
33+
timeout-minutes: 15
34+
runs-on: ubuntu-latest
35+
steps:
36+
- uses: actions/checkout@v4
37+
- name: Set up Docker Buildx
38+
uses: docker/setup-buildx-action@v3
39+
- name: Build and export to Docker
40+
uses: docker/build-push-action@v6
41+
with:
42+
file: api.Dockerfile
43+
load: true
44+
tags: api:test
45+
build-args: mode=playwright
46+
- name: Run Playwright tests
47+
run: |
48+
docker run --rm --name playwright \
49+
-v $(pwd)/test-results-docker-org:/test-results \
50+
-e CI=true \
51+
-e VUE_APP_SCOPE=organization \
52+
-e VUE_APP_GITHUB_ORG=octodemo \
53+
-e VUE_APP_GITHUB_API=/api/github \
54+
-e APP_MOCKED_DATA=true \
55+
-e VUE_APP_GITHUB_TOKEN=dummy \
56+
-e SESSION_SECRET=dummy \
57+
api:test "@org"
58+
- uses: actions/upload-artifact@v4
59+
if: ${{ !cancelled() }}
60+
with:
61+
name: playwright-report-docker-org
62+
path: test-results-docker-org/
63+
retention-days: 30
64+
65+
test-api-ent:
66+
timeout-minutes: 15
67+
runs-on: ubuntu-latest
68+
steps:
69+
- uses: actions/checkout@v4
70+
- name: Set up Docker Buildx
71+
uses: docker/setup-buildx-action@v3
72+
- name: Build and export to Docker
73+
uses: docker/build-push-action@v6
74+
with:
75+
file: api.Dockerfile
76+
load: true
77+
tags: api:test
78+
build-args: mode=playwright
79+
- name: Run Playwright tests
80+
run: |
81+
docker run --rm --name playwright \
82+
-v $(pwd)/test-results-docker-ent:/test-results \
83+
-e CI=true \
84+
-e VUE_APP_SCOPE=enterprise \
85+
-e VUE_APP_GITHUB_ENT=octodemo \
86+
-e VUE_APP_GITHUB_API=/api/github \
87+
-e APP_MOCKED_DATA=true \
88+
-e VUE_APP_GITHUB_TOKEN=dummy \
89+
-e SESSION_SECRET=dummy \
90+
api:test "@ent"
91+
- uses: actions/upload-artifact@v4
92+
if: ${{ !cancelled() }}
93+
with:
94+
name: playwright-report-docker-ent
95+
path: test-results-docker-ent/
96+
retention-days: 30

.gitignore

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,12 @@ pnpm-debug.log*
2525

2626
api/public
2727
test.http
28+
29+
/playwright-report/
30+
/blob-report/
31+
/playwright/.cache/
32+
33+
/test-results/
34+
/test-results-docker/
35+
test-results-docker-ent/
36+
test-results-docker-org/

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Stage 1: Build the Vue.js application
2-
FROM node:22 AS build-stage
2+
FROM node:23-alpine AS build-stage
33
WORKDIR /app
44
COPY package*.json ./
55
RUN npm install

api.Dockerfile

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,41 @@
11
# Stage 1: Build the Vue.js application
2-
FROM node:23 AS build-stage
2+
# mode can be 'prod' - default or 'playwright'
3+
# for 'playwright' mode, the final image will be base-playwright
4+
# for 'prod' mode, the final image will be base-prod
5+
# build with 'docker build -f api.Dockerfile -t api --build-arg mode=playwright .'
6+
# build with 'docker build -f api.Dockerfile -t api .' for production
7+
ARG mode=prod
8+
9+
FROM node:23-alpine AS build-stage
310

411
USER node
512
WORKDIR /app
613

714
COPY --chown=1000:1000 package*.json ./
8-
RUN npm install
15+
RUN npm ci
916
COPY --chown=1000:1000 . .
1017
RUN npm run build
1118

1219
# Stage 2: Prepare the Node.js API
13-
FROM node:23 AS api-stage
20+
FROM node:23-alpine AS base-prod
1421

1522
WORKDIR /api
1623

1724
# Copy package.json and other necessary files for the API
1825
COPY --chown=1000:1000 api/package*.json ./
19-
RUN npm install && \
26+
RUN npm ci && \
2027
chown -R 1000:1000 /api && \
21-
apt-get update && \
22-
apt-get install -y --no-install-recommends gettext-base && \
23-
apt-get clean && \
24-
rm -rf /var/lib/apt/lists/*
28+
apk update && \
29+
apk add --no-cache gettext && \
30+
rm -rf /var/cache/apk/*
2531

2632
# Copy the rest of your API source code
2733
COPY --chown=1000:1000 api/ .
2834

2935
# Copy the built Vue.js app from the previous stage
3036
COPY --chown=1000:1000 --from=build-stage /app/dist /api/public
3137
COPY --chown=1000:1000 --from=build-stage /app/dist/assets/app-config.js /api/app-config.template.js
38+
COPY --chown=1000:1000 --from=build-stage /app/mock-data /mock-data
3239

3340
# Expose the port your API will run on
3441
EXPOSE 3000
@@ -37,4 +44,29 @@ EXPOSE 3000
3744
RUN chmod +x /api/docker-entrypoint.api/entrypoint.sh
3845

3946
USER node
40-
ENTRYPOINT ["/api/docker-entrypoint.api/entrypoint.sh"]
47+
ENTRYPOINT ["/api/docker-entrypoint.api/entrypoint.sh"]
48+
49+
#-----------------------------------
50+
FROM mcr.microsoft.com/playwright:v1.49.1 AS base-playwright
51+
52+
WORKDIR /pw
53+
54+
RUN apt-get update && \
55+
apt-get install -y --no-install-recommends gettext-base && \
56+
apt-get clean && \
57+
rm -rf /var/lib/apt/lists/*
58+
59+
COPY --chown=1000:1000 --from=base-prod /api /api
60+
COPY --chown=1000:1000 --from=base-prod /mock-data /mock-data
61+
COPY --chown=1000:1000 tests ./tests
62+
COPY --chown=1000:1000 playwright.config.ts .
63+
COPY --chown=1000:1000 playwright.docker.config.ts .
64+
65+
66+
RUN npm install @playwright/[email protected]
67+
# RUN npx playwright install --with-deps
68+
69+
ENTRYPOINT [ "npx", "playwright", "test", "-c", "playwright.docker.config.ts", "--output", "/test-results", "--grep"]
70+
71+
#-----------------------------------
72+
FROM base-${mode} AS final

api/docker-entrypoint.api/entrypoint.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/bin/bash
1+
#!/bin/sh
22

33
configTemplateFile=/api/app-config.template.js
44
configTargetFile=/api/public/assets/app-config.js

api/server.mjs

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import axios from 'axios';
55
import { fileURLToPath } from 'url';
66
import session from 'express-session';
77
import { createProxyMiddleware } from 'http-proxy-middleware';
8+
import { readFileSync } from 'fs';
89
import MemoryStoreFactory from 'memorystore';
910
import RateLimit from 'express-rate-limit';
1011

@@ -58,16 +59,47 @@ const authMiddleware = (req, res, next) => {
5859
next();
5960
};
6061

62+
const simpleRequestLogger = (proxyServer, options) => {
63+
proxyServer.on('proxyReq', (proxyReq, req, res) => {
64+
console.log(`[HPM] [${req.method}] ${req.url}`); // outputs: [HPM] GET /users
65+
});
66+
}
67+
68+
const mockResponses = (proxyServer, options) => {
69+
proxyServer.on('proxyReq', (proxyReq, req, res) => {
70+
// Do not send to GitHub when mocked
71+
switch (req.path) {
72+
case "/orgs/octodemo/copilot/usage":
73+
res.json(JSON.parse(readFileSync(path.join(__dirname, '../mock-data/organization_response_sample.json'), 'utf8')));
74+
break;
75+
case "/orgs/octodemo/copilot/billing/seats":
76+
res.json(JSON.parse(readFileSync(path.join(__dirname, '../mock-data/organization_response_sample_seats.json'), 'utf8')));
77+
break;
78+
case "/enterprises/octodemo/copilot/usage":
79+
res.json(JSON.parse(readFileSync(path.join(__dirname, '../mock-data/enterprise_response_sample.json'), 'utf8')));
80+
break;
81+
case "/enterprises/octodemo/copilot/billing/seats":
82+
res.json(JSON.parse(readFileSync(path.join(__dirname, '../mock-data/enterprise_response_sample_seats.json'), 'utf8')));
83+
break;
84+
default:
85+
res.status(418).send('🫖Request Not Mocked');
86+
}
87+
});
88+
}
89+
90+
const plugins = [simpleRequestLogger];
91+
92+
if (process.env.APP_MOCKED_DATA === 'true') {
93+
plugins.push(mockResponses);
94+
}
95+
6196
const githubProxy = createProxyMiddleware({
6297
target: 'https://api.github.com',
6398
changeOrigin: true,
6499
pathRewrite: {
65100
'^/api/github': '', // Rewrite URL path (remove /api/github)
66101
},
67-
onProxyReq: (proxyReq, req) => {
68-
console.log('Proxying request to GitHub API:', req.url);
69-
// Optional: Modify the proxy request here (e.g., headers)
70-
},
102+
plugins
71103
});
72104

73105
// Apply middlewares to the app

0 commit comments

Comments
 (0)