-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add playwright create/login test for all db
- Loading branch information
Showing
10 changed files
with
608 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -38,3 +38,6 @@ web-vault | |
|
||
# Vaultwarden Resources | ||
resources | ||
|
||
# Playwright tests | ||
playwright |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
logs | ||
node_modules/ | ||
/test-results/ | ||
/playwright-report/ | ||
/playwright/.cache/ | ||
temp |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
# Integration tests | ||
|
||
This allows running integration tests using [Playwright](https://playwright.dev/). | ||
\ | ||
It usse its own [test.env](/test/scenarios/test.env) with different ports to not collide with a running dev instance. | ||
|
||
## Install | ||
|
||
```bash | ||
npm install | ||
npx playwright install firefox | ||
``` | ||
|
||
## Usage | ||
|
||
To run all the tests: | ||
|
||
```bash | ||
npx playwright test | ||
``` | ||
|
||
To access the ui to easily run test individually and debug if needed: | ||
|
||
```bash | ||
npx playwright test --ui | ||
``` | ||
|
||
### DB | ||
|
||
Projects are configured to allow to run tests only on specific database. | ||
\ | ||
You can use: | ||
|
||
```bash | ||
npx playwright test --project sqllite | ||
npx playwright test --project postgres | ||
npx playwright test --project mysql | ||
``` | ||
|
||
### Running specific tests | ||
|
||
To run a whole file you can : | ||
|
||
```bash | ||
npx playwright test --project=sqllite tests/login.spec.ts | ||
npx playwright test --project=sqllite login | ||
``` | ||
|
||
To run only a specifc test (It might fail if it has dependency): | ||
|
||
```bash | ||
npx playwright test --project=sqllite -g "Account creation" | ||
npx playwright test --project=sqllite tests/login.spec.ts:16 | ||
``` | ||
|
||
## Writing scenario | ||
|
||
When creating new scenario use the recorder to more easily identify elements (in general try to rely on visible hint to identify elements and not hidden ids). | ||
This does not start the server, you will need to start it manually. | ||
|
||
```bash | ||
npx playwright codegen "http://127.0.0.1:8000" | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
import { firefox, type FullConfig } from '@playwright/test'; | ||
import { exec, execSync } from 'node:child_process'; | ||
import fs from 'fs'; | ||
import yaml from 'js-yaml'; | ||
|
||
const utils = require('./global-utils'); | ||
|
||
utils.loadEnv(); | ||
|
||
function readCurrentVersion(){ | ||
try { | ||
const vw_version_file = fs.readFileSync('temp/web-vault/vw-version.json', { | ||
encoding: 'utf8', | ||
flag: 'r' | ||
}); | ||
|
||
return JSON.parse(vw_version_file)["version"]; | ||
} catch(err) { | ||
console.log(`Failed to read frontend current version: ${err}`); | ||
} | ||
} | ||
|
||
function readDockerVersion(){ | ||
try { | ||
const docker_settings = fs.readFileSync('../docker/DockerSettings.yaml', { | ||
encoding: 'utf8', | ||
flag: 'r' | ||
}); | ||
|
||
const settings = yaml.load(docker_settings); | ||
return settings["vault_version"]; | ||
} catch(err) { | ||
console.log(`Failed to read docker frontend current version: ${err}`); | ||
} | ||
} | ||
|
||
function retrieveFrontend(){ | ||
const vw_version = readCurrentVersion(); | ||
const vv = readDockerVersion() | ||
|
||
if( !vv ){ | ||
console.log("Empty docker frontend version"); | ||
process.exit(1); | ||
} | ||
|
||
try { | ||
if( vv != `v${vw_version}`) { | ||
fs.rmSync("./temp/web-vault", { recursive: true, force: true }); | ||
|
||
execSync(`cd temp && wget -c https://github.com/dani-garcia/bw_web_builds/releases/download/${vv}/bw_web_${vv}.tar.gz -O - | tar xz`, { stdio: "inherit" }); | ||
|
||
console.log(`Retrieved bw_web_builds-${vv}`); | ||
} else { | ||
console.log(`Using existing bw_web_builds-${vv}`); | ||
} | ||
} catch(err) { | ||
console.log(`Failed to retrieve frontend: ${err}`); | ||
process.exit(1); | ||
} | ||
} | ||
|
||
function buildServer(){ | ||
if( !fs.existsSync('temp/vaultwarden') ){ | ||
console.log("Rebuilding server"); | ||
execSync(`cd .. && cargo build --features sqlite,mysql,postgresql --release`, { stdio: "inherit" }); | ||
execSync(`cp ../target/release/vaultwarden temp/vaultwarden`, { stdio: "inherit" }); | ||
} else { | ||
console.log("Using existing server"); | ||
} | ||
} | ||
|
||
async function globalSetup(config: FullConfig) { | ||
execSync("mkdir -p temp/logs"); | ||
|
||
buildServer(); | ||
retrieveFrontend(); | ||
} | ||
|
||
export default globalSetup; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
import { type Browser, type TestInfo } from '@playwright/test'; | ||
import { execSync } from 'node:child_process'; | ||
import dotenv from 'dotenv'; | ||
import dotenvExpand from 'dotenv-expand'; | ||
|
||
const fs = require("fs"); | ||
const { spawn } = require('node:child_process'); | ||
|
||
function loadEnv(){ | ||
var myEnv = dotenv.config({ path: 'test.env' }); | ||
dotenvExpand.expand(myEnv); | ||
} | ||
|
||
async function waitFor(url: String, browser: Browser) { | ||
var ready = false; | ||
var context; | ||
|
||
do { | ||
try { | ||
context = await browser.newContext(); | ||
const page = await context.newPage(); | ||
await page.waitForTimeout(500); | ||
const result = await page.goto(url); | ||
ready = result.status() === 200; | ||
} catch(e) { | ||
if( !e.message.includes("CONNECTION_REFUSED") ){ | ||
throw e; | ||
} | ||
} finally { | ||
await context.close(); | ||
} | ||
} while(!ready); | ||
} | ||
|
||
function startStopSqlite(){ | ||
fs.rmSync("temp/db.sqlite3", { force: true }); | ||
fs.rmSync("temp/db.sqlite3-shm", { force: true }); | ||
fs.rmSync("temp/db.sqlite3-wal", { force: true }); | ||
} | ||
|
||
function startMariaDB() { | ||
console.log(`Starting MariaDB`); | ||
execSync(`docker run --rm --name ${process.env.MARIADB_CONTAINER} \ | ||
-e MARIADB_ROOT_PASSWORD=${process.env.MARIADB_PWD} \ | ||
-e MARIADB_USER=${process.env.MARIADB_USER} \ | ||
-e MARIADB_PASSWORD=${process.env.MARIADB_PWD} \ | ||
-e MARIADB_DATABASE=${process.env.MARIADB_DB} \ | ||
-p ${process.env.MARIADB_PORT}:3306 \ | ||
-d mariadb:10.4` | ||
); | ||
} | ||
|
||
|
||
function stopMariaDB() { | ||
console.log("Stopping MariaDB (ensure DB is wiped)"); | ||
execSync(`docker stop ${process.env.MARIADB_CONTAINER} || true`); | ||
} | ||
|
||
function startPostgres() { | ||
console.log(`Starting Postgres`); | ||
execSync(`docker run --rm --name ${process.env.POSTGRES_CONTAINER} \ | ||
-e POSTGRES_USER=${process.env.POSTGRES_USER} \ | ||
-e POSTGRES_PASSWORD=${process.env.POSTGRES_PWD} \ | ||
-e POSTGRES_DB=${process.env.POSTGRES_DB} \ | ||
-p ${process.env.POSTGRES_PORT}:5432 \ | ||
-d postgres:16.2` | ||
); | ||
}; | ||
|
||
function stopPostgres() { | ||
console.log("Stopping Postgres (Ensure DB is wiped)"); | ||
execSync(`docker stop ${process.env.POSTGRES_CONTAINER} || true`); | ||
} | ||
|
||
function dbConfig(testInfo: TestInfo){ | ||
switch(testInfo.project.name) { | ||
case "postgres": return { | ||
DATABASE_URL: `postgresql://${process.env.POSTGRES_USER}:${process.env.POSTGRES_PWD}@127.0.0.1:${process.env.POSTGRES_PORT}/${process.env.POSTGRES_DB}` | ||
} | ||
case "mysql": return { | ||
DATABASE_URL: `mysql://${process.env.MARIADB_USER}:${process.env.MARIADB_PWD}@127.0.0.1:${process.env.MARIADB_PORT}/${process.env.MARIADB_DB}` | ||
} | ||
default: return { I_REALLY_WANT_VOLATILE_STORAGE: true } | ||
} | ||
} | ||
|
||
async function startVaultwarden(browser: Browser, testInfo: TestInfo, env = {}, resetDB: Boolean = true) { | ||
if( resetDB ){ | ||
switch(testInfo.project.name) { | ||
case "postgres": | ||
stopPostgres(); | ||
startPostgres() | ||
break; | ||
case "mysql": | ||
stopMariaDB(); | ||
startMariaDB(); | ||
break; | ||
default: | ||
startStopSqlite(); | ||
} | ||
} | ||
|
||
const vw_log = fs.openSync("temp/logs/vaultwarden.log", "a"); | ||
var proc = spawn("temp/vaultwarden", { | ||
env: { ...process.env, ...env, ...dbConfig(testInfo) }, | ||
stdio: [process.stdin, vw_log, vw_log] | ||
}); | ||
|
||
await waitFor("/", browser); | ||
|
||
console.log(`Vaultwarden running on: ${process.env.DOMAIN}`); | ||
|
||
return proc; | ||
} | ||
|
||
async function stopVaultwarden(proc, testInfo: TestInfo, resetDB: Boolean = true) { | ||
console.log(`Vaultwarden stopping`); | ||
proc.kill(); | ||
|
||
if( resetDB ){ | ||
switch(testInfo.project.name) { | ||
case "postgres": | ||
stopPostgres(); | ||
break; | ||
case "mysql": | ||
stopMariaDB(); | ||
break; | ||
default: | ||
startStopSqlite(); | ||
} | ||
} | ||
} | ||
|
||
async function restartVaultwarden(proc, page: Page, testInfo: TestInfo, env, resetDB: Boolean = true) { | ||
stopVaultwarden(proc, testInfo, resetDB); | ||
return startVaultwarden(page.context().browser(), testInfo, env, resetDB); | ||
} | ||
|
||
export { loadEnv, waitFor, startVaultwarden, stopVaultwarden, restartVaultwarden }; |
Oops, something went wrong.