Skip to content

Commit

Permalink
end to end tests prototype
Browse files Browse the repository at this point in the history
  • Loading branch information
sdumetz committed Jan 27, 2025
1 parent df6e124 commit f84b312
Show file tree
Hide file tree
Showing 20 changed files with 1,101 additions and 2 deletions.
31 changes: 30 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -83,4 +83,33 @@ jobs:
name: "eCorpus-${{github.ref_name}}"
path: eCorpus
if-no-files-found: error
retention-days: 10
retention-days: 10
e2e:
name: Test End-to-End
runs-on: ubuntu-latest
needs: [ pack ]
steps:
- uses: actions/checkout@v4
with:
sparse-checkout: |
source/e2e
- uses: actions/download-artifact@v4
with:
name: "eCorpus-${{github.ref_name}}"
path: build
- uses: actions/setup-node@v4
with:
node-version: 22
cache: 'npm'
- name: install dependencies
run: |
ls
npm ci
(cd build && npm ci --omit=dev)
(cd source/e2e && npm ci)
(cd source/e2e && npx playwright install --with-deps)
- name: run tests
working-directory: source/e2e
env:
ROOT_DIR: "${{ github.workspace}}/build"
run: npm test
6 changes: 6 additions & 0 deletions source/e2e/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
node_modules/
/test-results/
/playwright-report/
/blob-report/
/playwright/.cache/
/playwright/.auth/
Binary file added source/e2e/__test_fixtures/cube.glb
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<h1>Article #1<br></h1><p><br data-mce-bogus="1"></p><p>This is the article content<br data-mce-bogus="1"></p>
1 change: 1 addition & 0 deletions source/e2e/__test_fixtures/scene.svx.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"asset":{"type":"application/si-dpo-3d.document+json","version":"1.0","copyright":"(c) Holusion SAS, all rights reserved","generator":"Voyager"},"scene":0,"scenes":[{"units":"m","meta":0,"nodes":[0,1,6],"setup":0}],"nodes":[{"id":"00000001","name":"Camera","camera":0},{"id":"00000002","name":"Lights","rotation":[0,0.6112574,0,0.7914319],"scale":[1,1,1],"children":[2,3,4,5]},{"id":"00000003","name":"Key","translation":[-0.8783957,0.9617225,1.6197255],"rotation":[0.4829741,-0.1070728,0.1880998,0.8484633],"scale":[0.3464102,0.3464102,0.3464102],"light":0},{"id":"00000004","name":"Fill #1","translation":[1.5828277,0.9357686,0.9690167],"rotation":[0.3546969,0.163893,-0.3861077,0.8356136],"scale":[0.3464102,0.3464102,0.3464102],"light":1},{"id":"00000005","name":"Fill #2","translation":[-1.2128678,-1.586092,0.5772901],"rotation":[0.9374013,-0.3018693,0.0532277,0.1652891],"scale":[0.3464102,0.3464102,0.3464102],"light":2},{"id":"00000006","name":"Rim","translation":[1.8054166,0.1076425,-1.0241503],"rotation":[0.373256,0.6426073,-0.5786063,0.3360813],"scale":[0.3464102,0.3464102,0.3464102],"light":3},{"id":"ecpfjsP48xwp","name":"Cube","meta":1,"model":0}],"cameras":[{"type":"perspective","perspective":{"yfov":52,"znear":0.0154239,"zfar":15.4238792},"autoNearFar":true}],"lights":[{"color":[1,0.95,0.9],"intensity":1,"type":"directional","shadowEnabled":true,"shadowSize":3.4641016},{"color":[0.9,0.95,1],"intensity":0.7,"type":"directional","shadowEnabled":true,"shadowSize":3.4641016},{"color":[0.8,0.85,1],"intensity":0.5,"type":"directional"},{"color":[0.85,0.9078313,1],"intensity":0.6,"type":"directional"}],"models":[{"units":"m","boundingBox":{"min":[-1,-1,-1],"max":[1,1,1]},"derivatives":[{"usage":"Web3D","quality":"High","assets":[{"uri":"models/cube.glb","type":"Model","byteSize":1936,"numFaces":12,"imageSize":8192}]}],"annotations":[{"id":"7v6L2wf64nmD","titles":{"EN":"Short Annotation"},"leads":{"EN":""},"position":[-0.9999999,0.1811343,0.0137845],"direction":[-0.9999846,-0.0039215,-0.0039215],"scale":0.0866025},{"id":"Of7CMr1ruYX5","titles":{"EN":"Extended Annotation"},"leads":{"EN":"with lead text"},"style":"Extended","position":[-0.0318588,0.1712172,1],"direction":[-0.0039215,-0.0039215,0.9999846],"scale":0.0866025},{"id":"hED2f4NxDFqR","titles":{"EN":"Link annotation"},"leads":{"EN":""},"articleId":"OKiTjtY6zrbJ","style":"Extended","position":[-0.18515,1,0.3567472],"direction":[-0.0039215,0.9999846,-0.0039215],"scale":0.0866025}]}],"metas":[{"collection":{"titles":{"EN":""},"intros":{"EN":""}}},{"collection":{"titles":{"EN":"cube_test","FR":"cube_test"},"intros":{"EN":""}},"articles":[{"id":"OKiTjtY6zrbJ","uris":{"EN":"articles/new-article-OKiTjtY6zrbJ-EN.html"},"titles":{"EN":"First article"},"leads":{"EN":"Lead text of first article"},"taglist":{"EN":["foo"]}}]}],"setups":[{"units":"cm","interface":{"visible":true,"logo":true,"menu":true,"tools":true},"viewer":{"shader":"Default","exposure":1,"gamma":2,"toneMapping":false,"isWallMountAR":false,"arScale":1},"reader":{"enabled":false,"position":"Overlay"},"navigation":{"type":"Orbit","enabled":true,"autoZoom":true,"lightsFollowCamera":true,"autoRotation":false,"orbit":{"orbit":[-25.0705596,-27.9480511,0],"offset":[0,0,3.8023018],"minOrbit":[-90,null,null],"maxOrbit":[90,null,null],"minOffset":[null,null,0.1],"maxOffset":[null,null,10000]}},"background":{"style":"RadialGradient","color0":[0.06,0.19,0.25],"color1":[0.04,0.04,0.04]},"floor":{"visible":false,"position":[0,-1,0],"size":2,"color":[0.6,0.75,0.8],"opacity":0.5,"receiveShadow":false,"autoSize":true},"grid":{"visible":false,"color":[0.5,0.7,0.8]},"tape":{"enabled":false},"slicer":{"enabled":false,"axis":"X","inverted":false,"position":0.5,"color":[0,0.61,0.87]},"language":{"language":"EN"},"environment":{"index":0},"audio":{"narrationId":""},"tours":[{"id":"6SJ7mM49SRTX","titles":{"EN":"New Tour #0"},"leads":{"EN":""},"steps":[{"id":"pwbF2C","titles":{"EN":"New Step #0"}},{"id":"FSMoQ5","titles":{"EN":"New Step #1"}}]}],"snapshots":{"features":["reader","viewer","navigation"],"targets":["scenes/0/setup/reader/enabled","scenes/0/setup/reader/position","scenes/0/setup/reader/articleId","scenes/0/setup/viewer/annotationsVisible","scenes/0/setup/viewer/activeAnnotation","scenes/0/setup/viewer/activeTags","scenes/0/setup/viewer/shader","scenes/0/setup/viewer/exposure","scenes/0/setup/navigation/orbit","scenes/0/setup/navigation/offset"],"states":[{"id":"scene-default","values":[false,0,"",false,"hED2f4NxDFqR","",0,1,[-28.2822384,-44.5417251,0],[0,0,3.8559698]],"curve":"EaseOutQuad","duration":1,"threshold":0},{"id":"pwbF2C","values":[false,0,"",false,"hED2f4NxDFqR","",0,1,[-28.2822384,-44.5417251,0],[0,0,3.8559698]],"curve":"EaseOutQuad","duration":1.5},{"id":"FSMoQ5","values":[false,0,"",true,"hED2f4NxDFqR","",0,1,[-31.4939173,75.3609513,0],[0,0,3.8559698]],"curve":"EaseOutQuad","duration":1.5}]}}]}
Binary file added source/e2e/__test_fixtures/scene.zip
Binary file not shown.
94 changes: 94 additions & 0 deletions source/e2e/eCorpus.setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import { test as setup, expect } from '@playwright/test';
import { randomBytes } from 'node:crypto';

const adminFile = 'playwright/.auth/admin.json';
const userFile = "playwright/.auth/user.json";
setup.use({
locale: "en-US",
});
/**
* To provide reasonable isolation on each test run, this setup uses a "master" admin account to create 2 new randomized
*/
setup("create superAdmin account", async ({request})=>{
//Expect instance to be in open mode
let res = await request.post("/users", {
data: JSON.stringify({
username: "testAdmin",
email: "[email protected]",
password: "12345678",
isAdministrator: true,
}),
headers:{
"Content-Type": "application/json",
}
});

if(res.status() == 401){
//Happens when setup is run multiple times against the same dev server
//ie. in watch mode
let res = await fetch("http://localhost:8000/users", {
headers: {
"Authorization": `Basic ${Buffer.from(`testAdmin:12345678`).toString("base64")}`
}
});
expect(res.status).toEqual(200);
}else{
expect(res.status()).toEqual(201);
}
});

setup('authenticate as admin', async ({ request }) => {
//Create administrator
const username = `testAdmin${randomBytes(2).readUInt16LE().toString(36)}`;
const password = randomBytes(16).toString("base64");
let res = await fetch("http://localhost:8000/users", {
method: "POST",
body: JSON.stringify({
username,
email: `${username}@example.com`,
password,
isAdministrator: true,
}),
headers:{
"Content-Type": "application/json",
"Authorization": `Basic ${Buffer.from(`testAdmin:12345678`).toString("base64")}`
}
});
expect(res.status).toEqual(201);

let post = await request.post("/auth/login", {
data: JSON.stringify({username, password}),
headers:{
"Content-Type": "application/json",
}
});
expect(post.status()).toEqual(200);
await request.storageState({ path: adminFile });
});

setup("authenticate as user", async ({request})=>{
const username = `testUser${randomBytes(2).readUInt16LE().toString(36)}`;
const password = randomBytes(16).toString("base64");
let res = await request.post("/users", {
data: JSON.stringify({
username,
email: `${username}@example.com`,
password,
isAdministrator: false,
}),
headers:{
"Content-Type": "application/json",
"Authorization": `Basic ${Buffer.from(`testAdmin:12345678`).toString("base64")}`
}
});
expect(res.status()).toEqual(201);

res = await request.post("/auth/login", {
data: JSON.stringify({username, password}),
headers:{
"Content-Type": "application/json",
}
});
expect(res.status()).toEqual(200);
await request.storageState({ path: userFile });
})
143 changes: 143 additions & 0 deletions source/e2e/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 21 additions & 0 deletions source/e2e/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"name": "e2e",
"version": "1.0.0",
"description": "",
"main": "index.js",
"type": "module",
"scripts": {
"test": "playwright test"
},
"author": "",
"license": "ISC",
"devDependencies": {
"@playwright/test": "^1.49.1",
"@types/node": "^22.10.7"
},
"dependencies": {
"@types/yauzl": "^2.10.3",
"xml-js": "^1.6.11",
"yauzl": "^3.2.0"
}
}
56 changes: 56 additions & 0 deletions source/e2e/playwright.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { defineConfig, devices } from '@playwright/test';
import path from 'path';

/**
* Read environment variables from file.
* https://github.com/motdotla/dotenv
*/
// import dotenv from 'dotenv';
// import path from 'path';
// dotenv.config({ path: path.resolve(__dirname, '.env') });

/**
* See https://playwright.dev/docs/test-configuration.
*/
export default defineConfig({
testDir: './tests',
/* Run tests in files in parallel */
fullyParallel: true,
/* Fail the build on CI if you accidentally left test.only in the source code. */
forbidOnly: !!process.env.CI,
/* Retry on CI only */
retries: process.env.CI ? 2 : 0,
/* Opt out of parallel tests on CI. */
workers: process.env.CI ? 1 : undefined,
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
reporter: 'line',
use: {
baseURL: 'http://localhost:8000',
trace: 'on-first-retry',
},

projects: [
{
name: "setup",
testDir: ".",
testMatch: /.*\.setup\.ts/
},
{
name: 'chromium',
use: {
...devices['Desktop Chrome'],
storageState: 'playwright/.auth/admin.json',
},
dependencies: ['setup'],
},
],

/* Run your local dev server before starting the tests */
webServer: {
command: `${path.resolve(import.meta.dirname, "start_server.sh")}`,
url: 'http://127.0.0.1:8000',
reuseExistingServer: !process.env.CI,
stdout: 'pipe',
stderr: 'pipe',
},
});
18 changes: 18 additions & 0 deletions source/e2e/start_server.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/bin/sh
set -e
#clean up previous runs
rm -rf /tmp/ecorpus-test-server.*

TMP="$(mktemp -d /tmp/ecorpus-test-server.XXXXX)"

: "${ROOT_DIR:="$( cd "$( dirname "$0" )/../.." && pwd )"}"
: "${FILES_DIR:="$TMP"}"

export ROOT_DIR
export FILES_DIR

(
set -e
cd "$ROOT_DIR"
npm start
)
Loading

0 comments on commit f84b312

Please sign in to comment.