Spiegel von
https://github.com/dani-garcia/vaultwarden.git
synchronisiert 2024-11-16 04:12:53 +01:00
Add playwright create/login test for all db
Dieser Commit ist enthalten in:
Ursprung
0fe93edea6
Commit
963eef7be9
10 geänderte Dateien mit 608 neuen und 0 gelöschten Zeilen
|
@ -38,3 +38,6 @@ web-vault
|
||||||
|
|
||||||
# Vaultwarden Resources
|
# Vaultwarden Resources
|
||||||
resources
|
resources
|
||||||
|
|
||||||
|
# Playwright tests
|
||||||
|
playwright
|
||||||
|
|
6
playwright/.gitignore
gevendort
Normale Datei
6
playwright/.gitignore
gevendort
Normale Datei
|
@ -0,0 +1,6 @@
|
||||||
|
logs
|
||||||
|
node_modules/
|
||||||
|
/test-results/
|
||||||
|
/playwright-report/
|
||||||
|
/playwright/.cache/
|
||||||
|
temp
|
63
playwright/README.md
Normale Datei
63
playwright/README.md
Normale Datei
|
@ -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"
|
||||||
|
```
|
79
playwright/global-setup.ts
Normale Datei
79
playwright/global-setup.ts
Normale Datei
|
@ -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;
|
139
playwright/global-utils.ts
Normale Datei
139
playwright/global-utils.ts
Normale Datei
|
@ -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 };
|
155
playwright/package-lock.json
generiert
Normale Datei
155
playwright/package-lock.json
generiert
Normale Datei
|
@ -0,0 +1,155 @@
|
||||||
|
{
|
||||||
|
"name": "scenarios",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"lockfileVersion": 3,
|
||||||
|
"requires": true,
|
||||||
|
"packages": {
|
||||||
|
"": {
|
||||||
|
"name": "scenarios",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"license": "ISC",
|
||||||
|
"devDependencies": {
|
||||||
|
"@playwright/test": "^1.41.2",
|
||||||
|
"@types/node": "^20.11.16",
|
||||||
|
"abort-controller": "3.0.0",
|
||||||
|
"dotenv": "^16.4.1",
|
||||||
|
"dotenv-expand": "^10.0.0",
|
||||||
|
"js-yaml": "4.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@playwright/test": {
|
||||||
|
"version": "1.41.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.41.2.tgz",
|
||||||
|
"integrity": "sha512-qQB9h7KbibJzrDpkXkYvsmiDJK14FULCCZgEcoe2AvFAS64oCirWTwzTlAYEbKaRxWs5TFesE1Na6izMv3HfGg==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"playwright": "1.41.2"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"playwright": "cli.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@types/node": {
|
||||||
|
"version": "20.11.16",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.16.tgz",
|
||||||
|
"integrity": "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"undici-types": "~5.26.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/abort-controller": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"event-target-shim": "^5.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/argparse": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"node_modules/dotenv": {
|
||||||
|
"version": "16.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.1.tgz",
|
||||||
|
"integrity": "sha512-CjA3y+Dr3FyFDOAMnxZEGtnW9KBR2M0JvvUtXNW+dYJL5ROWxP9DUHCwgFqpMk0OXCc0ljhaNTr2w/kutYIcHQ==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/motdotla/dotenv?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/dotenv-expand": {
|
||||||
|
"version": "10.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-10.0.0.tgz",
|
||||||
|
"integrity": "sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/event-target-shim": {
|
||||||
|
"version": "5.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
|
||||||
|
"integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/fsevents": {
|
||||||
|
"version": "2.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
|
||||||
|
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
|
||||||
|
"dev": true,
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"darwin"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/js-yaml": {
|
||||||
|
"version": "4.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
|
||||||
|
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"argparse": "^2.0.1"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"js-yaml": "bin/js-yaml.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/playwright": {
|
||||||
|
"version": "1.41.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.41.2.tgz",
|
||||||
|
"integrity": "sha512-v0bOa6H2GJChDL8pAeLa/LZC4feoAMbSQm1/jF/ySsWWoaNItvrMP7GEkvEEFyCTUYKMxjQKaTSg5up7nR6/8A==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"playwright-core": "1.41.2"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"playwright": "cli.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16"
|
||||||
|
},
|
||||||
|
"optionalDependencies": {
|
||||||
|
"fsevents": "2.3.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/playwright-core": {
|
||||||
|
"version": "1.41.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.41.2.tgz",
|
||||||
|
"integrity": "sha512-VaTvwCA4Y8kxEe+kfm2+uUUw5Lubf38RxF7FpBxLPmGe5sdNkSg5e3ChEigaGrX7qdqT3pt2m/98LiyvU2x6CA==",
|
||||||
|
"dev": true,
|
||||||
|
"bin": {
|
||||||
|
"playwright-core": "cli.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/undici-types": {
|
||||||
|
"version": "5.26.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
|
||||||
|
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
18
playwright/package.json
Normale Datei
18
playwright/package.json
Normale Datei
|
@ -0,0 +1,18 @@
|
||||||
|
{
|
||||||
|
"name": "scenarios",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"devDependencies": {
|
||||||
|
"@playwright/test": "^1.41.2",
|
||||||
|
"@types/node": "^20.11.16",
|
||||||
|
"abort-controller": "3.0.0",
|
||||||
|
"dotenv": "^16.4.1",
|
||||||
|
"dotenv-expand": "^10.0.0",
|
||||||
|
"js-yaml": "4.1.0"
|
||||||
|
}
|
||||||
|
}
|
54
playwright/playwright.config.ts
Normale Datei
54
playwright/playwright.config.ts
Normale Datei
|
@ -0,0 +1,54 @@
|
||||||
|
import { defineConfig, devices } from '@playwright/test';
|
||||||
|
import { exec } from 'node:child_process';
|
||||||
|
|
||||||
|
const utils = require('./global-utils');
|
||||||
|
|
||||||
|
utils.loadEnv();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See https://playwright.dev/docs/test-configuration.
|
||||||
|
*/
|
||||||
|
export default defineConfig({
|
||||||
|
testDir: 'tests',
|
||||||
|
/* Run tests in files in parallel */
|
||||||
|
fullyParallel: false,
|
||||||
|
|
||||||
|
/* 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,
|
||||||
|
workers: 1,
|
||||||
|
|
||||||
|
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
|
||||||
|
reporter: 'html',
|
||||||
|
timeout: 10 * 1000,
|
||||||
|
expect: { timeout: 10 * 1000 },
|
||||||
|
|
||||||
|
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
|
||||||
|
use: {
|
||||||
|
/* Base URL to use in actions like `await page.goto('/')`. */
|
||||||
|
baseURL: process.env.DOMAIN,
|
||||||
|
|
||||||
|
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
|
||||||
|
trace: 'on-first-retry',
|
||||||
|
},
|
||||||
|
|
||||||
|
/* Configure projects for major browsers */
|
||||||
|
projects: [
|
||||||
|
{
|
||||||
|
name: 'sqllite',
|
||||||
|
use: { ...devices['Desktop Firefox'] },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'postgres',
|
||||||
|
use: { ...devices['Desktop Firefox'] },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'mysql',
|
||||||
|
use: { ...devices['Desktop Firefox'] },
|
||||||
|
},
|
||||||
|
],
|
||||||
|
|
||||||
|
globalSetup: require.resolve('./global-setup'),
|
||||||
|
});
|
37
playwright/test.env
Normale Datei
37
playwright/test.env
Normale Datei
|
@ -0,0 +1,37 @@
|
||||||
|
##################################################################
|
||||||
|
### Shared Playwright conf test file Vaultwarden and Databases ###
|
||||||
|
##################################################################
|
||||||
|
|
||||||
|
#############
|
||||||
|
# Test user #
|
||||||
|
#############
|
||||||
|
TEST_USER=test
|
||||||
|
TEST_USER_PASSWORD=${TEST_USER}
|
||||||
|
TEST_USER_MAIL="${TEST_USER}@example.com"
|
||||||
|
|
||||||
|
######################
|
||||||
|
# Vaultwarden Config #
|
||||||
|
######################
|
||||||
|
DATA_FOLDER=temp
|
||||||
|
WEB_VAULT_FOLDER=temp/web-vault/
|
||||||
|
|
||||||
|
ROCKET_PORT=8001
|
||||||
|
DOMAIN=http://127.0.0.1:${ROCKET_PORT}
|
||||||
|
|
||||||
|
###########################
|
||||||
|
# Docker MariaDb container#
|
||||||
|
###########################
|
||||||
|
MARIADB_CONTAINER=vw-mariadb-test
|
||||||
|
MARIADB_PORT=3307
|
||||||
|
MARIADB_USER=vaultwarden
|
||||||
|
MARIADB_PWD=vaultwarden
|
||||||
|
MARIADB_DB=vaultwarden
|
||||||
|
|
||||||
|
############################
|
||||||
|
# Docker Postgres container#
|
||||||
|
############################
|
||||||
|
POSTGRES_CONTAINER=vw-postgres-test
|
||||||
|
POSTGRES_PORT=5433
|
||||||
|
POSTGRES_USER=vaultwarden
|
||||||
|
POSTGRES_PWD=vaultwarden
|
||||||
|
POSTGRES_DB=vaultwarden
|
54
playwright/tests/login.spec.ts
Normale Datei
54
playwright/tests/login.spec.ts
Normale Datei
|
@ -0,0 +1,54 @@
|
||||||
|
import { test, expect, type TestInfo } from '@playwright/test';
|
||||||
|
const utils = require('../global-utils');
|
||||||
|
|
||||||
|
utils.loadEnv();
|
||||||
|
|
||||||
|
var proc;
|
||||||
|
|
||||||
|
test.beforeAll('Setup', async ({ browser }, testInfo: TestInfo) => {
|
||||||
|
proc = await utils.startVaultwarden(browser, testInfo, {});
|
||||||
|
});
|
||||||
|
|
||||||
|
test.afterAll('Teardown', async ({}, testInfo: TestInfo) => {
|
||||||
|
utils.stopVaultwarden(proc, testInfo);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Account creation', async ({ page }) => {
|
||||||
|
// Landing page
|
||||||
|
await page.goto('/');
|
||||||
|
await page.getByRole('link', { name: 'Create account' }).click();
|
||||||
|
|
||||||
|
// Back to Vault create account
|
||||||
|
await expect(page).toHaveTitle(/Create account | Vaultwarden Web/);
|
||||||
|
await page.getByLabel(/Email address/).fill(process.env.TEST_USER_MAIL);
|
||||||
|
await page.getByLabel('Name').fill(process.env.TEST_USER);
|
||||||
|
await page.getByLabel('Master password\n (required)', { exact: true }).fill('Master password');
|
||||||
|
await page.getByLabel('Re-type master password').fill('Master password');
|
||||||
|
await page.getByRole('button', { name: 'Create account' }).click();
|
||||||
|
|
||||||
|
// Back to the login page
|
||||||
|
await expect(page).toHaveTitle('Vaultwarden Web');
|
||||||
|
await page.getByLabel('Your new account has been created')
|
||||||
|
await page.getByRole('button', { name: 'Continue' }).click();
|
||||||
|
|
||||||
|
// Unlock page
|
||||||
|
await page.getByLabel('Master password').fill('Master password');
|
||||||
|
await page.getByRole('button', { name: 'Log in with master password' }).click();
|
||||||
|
|
||||||
|
// We are now in the default vault page
|
||||||
|
await expect(page).toHaveTitle(/Vaults/);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Master password login', async ({ page }) => {
|
||||||
|
// Landing page
|
||||||
|
await page.goto('/');
|
||||||
|
await page.getByLabel(/Email address/).fill(process.env.TEST_USER_MAIL);
|
||||||
|
await page.getByRole('button', { name: 'Continue' }).click();
|
||||||
|
|
||||||
|
// Unlock page
|
||||||
|
await page.getByLabel('Master password').fill('Master password');
|
||||||
|
await page.getByRole('button', { name: 'Log in with master password' }).click();
|
||||||
|
|
||||||
|
// We are now in the default vault page
|
||||||
|
await expect(page).toHaveTitle(/Vaults/);
|
||||||
|
});
|
Laden …
In neuem Issue referenzieren