mirror of
https://github.com/steveiliop56/tinyauth.git
synced 2026-07-17 23:41:11 +00:00
feat: add simple e2e tests
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
# playwright files
|
||||
/node_modules/
|
||||
/test-results/
|
||||
/playwright-report/
|
||||
/blob-report/
|
||||
/playwright/.cache/
|
||||
/playwright/.auth/
|
||||
@@ -0,0 +1,22 @@
|
||||
appUrl: http://tinyauth.127.0.0.1.sslip.io
|
||||
|
||||
log:
|
||||
level: debug
|
||||
|
||||
auth:
|
||||
users:
|
||||
# user1:password,user2:password,user3:password:token
|
||||
- user1:$2a$10$h1laww4k5a4bJcG5KwE3nO45YKSC4mOKHxbcccgxr3Y7H9zHlQe8e
|
||||
- user2:$2a$10$h1laww4k5a4bJcG5KwE3nO45YKSC4mOKHxbcccgxr3Y7H9zHlQe8e
|
||||
- user3:$2a$10$h1laww4k5a4bJcG5KwE3nO45YKSC4mOKHxbcccgxr3Y7H9zHlQe8e:MVR4JQWNXYKNM6HHJEYEFP2O74QIIEJE
|
||||
# disable rate limits for multiple workers to work
|
||||
loginMaxRetries: 0
|
||||
|
||||
apps:
|
||||
whoami:
|
||||
config:
|
||||
domain: whoami.127.0.0.1.sslip.io
|
||||
path:
|
||||
allow: /foo
|
||||
users:
|
||||
allow: user1
|
||||
@@ -0,0 +1,34 @@
|
||||
services:
|
||||
traefik:
|
||||
image: traefik:v3.6
|
||||
command: |
|
||||
--api.insecure=true
|
||||
--providers.docker
|
||||
--entrypoints.web.address=:80
|
||||
ports:
|
||||
- 80:80
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
|
||||
whoami:
|
||||
image: traefik/whoami:latest
|
||||
labels:
|
||||
traefik.enable: true
|
||||
traefik.http.routers.whoami.rule: Host(`whoami.127.0.0.1.sslip.io`)
|
||||
traefik.http.routers.whoami.middlewares: tinyauth
|
||||
|
||||
tinyauth:
|
||||
build:
|
||||
context: ../
|
||||
dockerfile: Dockerfile
|
||||
args:
|
||||
- VERSION=e2e
|
||||
- BUILD_TAGS=nomsgpack
|
||||
- LD_FLAGS=-s -w
|
||||
command: ["--configfile", "/app/config.yaml"]
|
||||
volumes:
|
||||
- ./config.e2e.yaml:/app/config.yaml:ro
|
||||
labels:
|
||||
traefik.enable: true
|
||||
traefik.http.routers.tinyauth.rule: Host(`tinyauth.127.0.0.1.sslip.io`)
|
||||
traefik.http.middlewares.tinyauth.forwardauth.address: http://tinyauth:3000/api/auth/traefik
|
||||
@@ -0,0 +1,47 @@
|
||||
import {expect, Page} from '@playwright/test';
|
||||
import { OTP } from 'otplib';
|
||||
|
||||
export class LoginFixture {
|
||||
constructor(public readonly page: Page) {}
|
||||
|
||||
async run(username: string, password: string) {
|
||||
await expect(this.page.getByText('Welcome back, please login')).toBeVisible();
|
||||
await this.page.getByLabel('Username').fill(username);
|
||||
await this.page.getByLabel('Password').fill(password);
|
||||
await this.page.getByRole('button', { name: 'Login' }).click();
|
||||
}
|
||||
|
||||
async expectSuccess(username: string) {
|
||||
await expect(this.page.getByText(`You are currently logged in as ${username}.`)).toBeVisible()
|
||||
}
|
||||
}
|
||||
|
||||
export class LogoutFixture {
|
||||
constructor(public readonly page: Page) {}
|
||||
|
||||
async run() {
|
||||
await expect(this.page.getByText('Click the button below to logout.')).toBeVisible();
|
||||
await this.page.getByRole('button', { name: 'Logout' }).click();
|
||||
}
|
||||
|
||||
async expectSuccess() {
|
||||
await expect(this.page.getByText('Welcome back, please login')).toBeVisible();
|
||||
}
|
||||
}
|
||||
|
||||
export class TOTPFixture {
|
||||
constructor(public readonly page: Page) {}
|
||||
|
||||
async run(secret: string) {
|
||||
await expect(this.page.getByText('Enter your TOTP code')).toBeVisible();
|
||||
const otp = new OTP();
|
||||
const token = await otp.generate({ secret });
|
||||
await this.page.getByPlaceholder('XXXXXX').fill(token);
|
||||
// we shouldn't need to click continue, it will auto submit
|
||||
// await this.page.getByRole('button', { name: 'Continue' }).click();
|
||||
}
|
||||
|
||||
async expectSuccess(username: string) {
|
||||
await expect(this.page.getByText(`You are currently logged in as ${username}.`)).toBeVisible()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"name": "e2e",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"down": "docker compose -f docker-compose.e2e.yml down",
|
||||
"up": "docker compose -f docker-compose.e2e.yml up --build --pull=always --force-recreate --remove-orphans",
|
||||
"test": "playwright test",
|
||||
"report": "playwright show-report"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"devEngines": {
|
||||
"packageManager": {
|
||||
"name": "pnpm",
|
||||
"version": "^11.1.2",
|
||||
"onFail": "download"
|
||||
}
|
||||
},
|
||||
"type": "module",
|
||||
"devDependencies": {
|
||||
"@playwright/test": "^1.61.1",
|
||||
"@types/node": "^26.1.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"otplib": "^13.4.1"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
import { defineConfig, devices } from '@playwright/test';
|
||||
|
||||
export default defineConfig({
|
||||
testDir: './specs',
|
||||
fullyParallel: true,
|
||||
forbidOnly: false,
|
||||
retries: 0,
|
||||
workers: 4,
|
||||
reporter: 'html',
|
||||
use: {
|
||||
trace: 'on-first-retry',
|
||||
video: 'on',
|
||||
},
|
||||
projects: [
|
||||
{
|
||||
name: 'chromium',
|
||||
use: { ...devices['Desktop Chrome'] },
|
||||
},
|
||||
{
|
||||
name: 'firefox',
|
||||
use: { ...devices['Desktop Firefox'] },
|
||||
},
|
||||
|
||||
{
|
||||
name: 'webkit',
|
||||
use: { ...devices['Desktop Safari'] },
|
||||
},
|
||||
{
|
||||
name: 'Mobile Chrome',
|
||||
use: { ...devices['Pixel 5'] },
|
||||
},
|
||||
{
|
||||
name: 'Mobile Safari',
|
||||
use: { ...devices['iPhone 12'] },
|
||||
},
|
||||
],
|
||||
webServer: {
|
||||
command: 'docker compose -f docker-compose.e2e.yml up --build --pull=always --force-recreate --remove-orphans',
|
||||
url: 'http://tinyauth.127.0.0.1.sslip.io/api/healthz',
|
||||
reuseExistingServer: true,
|
||||
gracefulShutdown: {
|
||||
signal: 'SIGINT',
|
||||
timeout: 1000,
|
||||
},
|
||||
},
|
||||
});
|
||||
Generated
+338
@@ -0,0 +1,338 @@
|
||||
---
|
||||
lockfileVersion: '9.0'
|
||||
|
||||
importers:
|
||||
|
||||
.:
|
||||
configDependencies: {}
|
||||
packageManagerDependencies:
|
||||
'@pnpm/exe':
|
||||
specifier: ^11.1.2
|
||||
version: 11.13.1
|
||||
pnpm:
|
||||
specifier: ^11.1.2
|
||||
version: 11.13.1
|
||||
|
||||
packages:
|
||||
|
||||
'@pnpm/exe@11.13.1':
|
||||
resolution: {integrity: sha512-P4euEK6lOFnd5oTHEc5M/HhvyF4XUhTnVsklEcM6rmY0QJxPD6xbT+u1+gskEIBp4nSRorz20IJQtAU1Nerggg==}
|
||||
hasBin: true
|
||||
|
||||
'@pnpm/linux-arm64@11.13.1':
|
||||
resolution: {integrity: sha512-wB8zloqrYrudPyuA5qbuTCnJGe4eETPwqOjoPjoyyyvA4zFI5XfLpxgqOOcaY5UJBoqzckcGpRVDwhSRfsQ/6A==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
'@pnpm/linux-x64@11.13.1':
|
||||
resolution: {integrity: sha512-A+wnEvzfWEvanXiwww3tnOPmtjPSrrf5tOP6vk8+K0BRFEe/Df0oPytm2nWgGcn5iwPnqtr1Btkof913McnSPA==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
'@pnpm/linuxstatic-arm64@11.13.1':
|
||||
resolution: {integrity: sha512-k4t65VeqRX4COMFe45TF58CVmCpmAsKZShaR1HobmUeleo98mWTctggKolrA2MHcVUeSS+12yB5Urb3uDazhmw==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@pnpm/linuxstatic-x64@11.13.1':
|
||||
resolution: {integrity: sha512-A65GqPzwCl0bAMk3kRWfbjSRBm5RRaqR2oMxV/9AYZrwO0X9yEfngbLBISCPHjt6/Qe4nH7DFemyhy6yODYwEw==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@pnpm/macos-arm64@11.13.1':
|
||||
resolution: {integrity: sha512-MJvOtyGOWSfBoqdVEfAH8ljmHs13mt82k/UxN4f+q7koDxJRR2n4Nie6Og6RwbnbaubCz0Fh2bTeL1+MxDSFpA==}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@pnpm/win-arm64@11.13.1':
|
||||
resolution: {integrity: sha512-kl/g1cCKOJPe4HntspyrAJW0LRco0UHnVfxHSspezo4Zj4AanJAZ8WzLqfa6/w3lBSKHTEN4x0pb3m4J7B7Vpw==}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
|
||||
'@pnpm/win-x64@11.13.1':
|
||||
resolution: {integrity: sha512-Bcb14NeBlbHS2Gq1qr8VnCiAz5eC1lYzXOls7zH0bnV0Taaj4/xyfm0HVO4dn9R2TQtVtz1qnBZHHL9PDFumqQ==}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@reflink/reflink-darwin-arm64@0.1.19':
|
||||
resolution: {integrity: sha512-ruy44Lpepdk1FqDz38vExBY/PVUsjxZA+chd9wozjUH9JjuDT/HEaQYA6wYN9mf041l0yLVar6BCZuWABJvHSA==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@reflink/reflink-darwin-x64@0.1.19':
|
||||
resolution: {integrity: sha512-By85MSWrMZa+c26TcnAy8SDk0sTUkYlNnwknSchkhHpGXOtjNDUOxJE9oByBnGbeuIE1PiQsxDG3Ud+IVV9yuA==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@reflink/reflink-linux-arm64-gnu@0.1.19':
|
||||
resolution: {integrity: sha512-7P+er8+rP9iNeN+bfmccM4hTAaLP6PQJPKWSA4iSk2bNvo6KU6RyPgYeHxXmzNKzPVRcypZQTpFgstHam6maVg==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@reflink/reflink-linux-arm64-musl@0.1.19':
|
||||
resolution: {integrity: sha512-37iO/Dp6m5DDaC2sf3zPtx/hl9FV3Xze4xoYidrxxS9bgP3S8ALroxRK6xBG/1TtfXKTvolvp+IjrUU6ujIGmA==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@reflink/reflink-linux-x64-gnu@0.1.19':
|
||||
resolution: {integrity: sha512-jbI8jvuYCaA3MVUdu8vLoLAFqC+iNMpiSuLbxlAgg7x3K5bsS8nOpTRnkLF7vISJ+rVR8W+7ThXlXlUQ93ulkw==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@reflink/reflink-linux-x64-musl@0.1.19':
|
||||
resolution: {integrity: sha512-e9FBWDe+lv7QKAwtKOt6A2W/fyy/aEEfr0g6j/hWzvQcrzHCsz07BNQYlNOjTfeytrtLU7k449H1PI95jA4OjQ==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@reflink/reflink-win32-arm64-msvc@0.1.19':
|
||||
resolution: {integrity: sha512-09PxnVIQcd+UOn4WAW73WU6PXL7DwGS6wPlkMhMg2zlHHG65F3vHepOw06HFCq+N42qkaNAc8AKIabWvtk6cIQ==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
|
||||
'@reflink/reflink-win32-x64-msvc@0.1.19':
|
||||
resolution: {integrity: sha512-E//yT4ni2SyhwP8JRjVGWr3cbnhWDiPLgnQ66qqaanjjnMiu3O/2tjCPQXlcGc/DEYofpDc9fvhv6tALQsMV9w==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@reflink/reflink@0.1.19':
|
||||
resolution: {integrity: sha512-DmCG8GzysnCZ15bres3N5AHCmwBwYgp0As6xjhQ47rAUTUXxJiK+lLUxaGsX3hd/30qUpVElh05PbGuxRPgJwA==}
|
||||
engines: {node: '>= 10'}
|
||||
|
||||
detect-libc@2.1.2:
|
||||
resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
pnpm@11.13.1:
|
||||
resolution: {integrity: sha512-svx2g7imUlQU59E+G6KMqt3elr9m7FQL+ut+cCuB8+C+TR8pXt9/n+A5Z0Co3ORQnFgt33mJH0VD/qMtN2RfJQ==}
|
||||
engines: {node: '>=22.13'}
|
||||
hasBin: true
|
||||
|
||||
snapshots:
|
||||
|
||||
'@pnpm/exe@11.13.1':
|
||||
dependencies:
|
||||
'@reflink/reflink': 0.1.19
|
||||
detect-libc: 2.1.2
|
||||
optionalDependencies:
|
||||
'@pnpm/linux-arm64': 11.13.1
|
||||
'@pnpm/linux-x64': 11.13.1
|
||||
'@pnpm/linuxstatic-arm64': 11.13.1
|
||||
'@pnpm/linuxstatic-x64': 11.13.1
|
||||
'@pnpm/macos-arm64': 11.13.1
|
||||
'@pnpm/win-arm64': 11.13.1
|
||||
'@pnpm/win-x64': 11.13.1
|
||||
|
||||
'@pnpm/linux-arm64@11.13.1':
|
||||
optional: true
|
||||
|
||||
'@pnpm/linux-x64@11.13.1':
|
||||
optional: true
|
||||
|
||||
'@pnpm/linuxstatic-arm64@11.13.1':
|
||||
optional: true
|
||||
|
||||
'@pnpm/linuxstatic-x64@11.13.1':
|
||||
optional: true
|
||||
|
||||
'@pnpm/macos-arm64@11.13.1':
|
||||
optional: true
|
||||
|
||||
'@pnpm/win-arm64@11.13.1':
|
||||
optional: true
|
||||
|
||||
'@pnpm/win-x64@11.13.1':
|
||||
optional: true
|
||||
|
||||
'@reflink/reflink-darwin-arm64@0.1.19':
|
||||
optional: true
|
||||
|
||||
'@reflink/reflink-darwin-x64@0.1.19':
|
||||
optional: true
|
||||
|
||||
'@reflink/reflink-linux-arm64-gnu@0.1.19':
|
||||
optional: true
|
||||
|
||||
'@reflink/reflink-linux-arm64-musl@0.1.19':
|
||||
optional: true
|
||||
|
||||
'@reflink/reflink-linux-x64-gnu@0.1.19':
|
||||
optional: true
|
||||
|
||||
'@reflink/reflink-linux-x64-musl@0.1.19':
|
||||
optional: true
|
||||
|
||||
'@reflink/reflink-win32-arm64-msvc@0.1.19':
|
||||
optional: true
|
||||
|
||||
'@reflink/reflink-win32-x64-msvc@0.1.19':
|
||||
optional: true
|
||||
|
||||
'@reflink/reflink@0.1.19':
|
||||
optionalDependencies:
|
||||
'@reflink/reflink-darwin-arm64': 0.1.19
|
||||
'@reflink/reflink-darwin-x64': 0.1.19
|
||||
'@reflink/reflink-linux-arm64-gnu': 0.1.19
|
||||
'@reflink/reflink-linux-arm64-musl': 0.1.19
|
||||
'@reflink/reflink-linux-x64-gnu': 0.1.19
|
||||
'@reflink/reflink-linux-x64-musl': 0.1.19
|
||||
'@reflink/reflink-win32-arm64-msvc': 0.1.19
|
||||
'@reflink/reflink-win32-x64-msvc': 0.1.19
|
||||
|
||||
detect-libc@2.1.2: {}
|
||||
|
||||
pnpm@11.13.1: {}
|
||||
|
||||
---
|
||||
lockfileVersion: '9.0'
|
||||
|
||||
settings:
|
||||
autoInstallPeers: true
|
||||
excludeLinksFromLockfile: false
|
||||
|
||||
importers:
|
||||
|
||||
.:
|
||||
dependencies:
|
||||
otplib:
|
||||
specifier: ^13.4.1
|
||||
version: 13.4.1
|
||||
devDependencies:
|
||||
'@playwright/test':
|
||||
specifier: ^1.61.1
|
||||
version: 1.61.1
|
||||
'@types/node':
|
||||
specifier: ^26.1.1
|
||||
version: 26.1.1
|
||||
|
||||
packages:
|
||||
|
||||
'@noble/hashes@2.2.0':
|
||||
resolution: {integrity: sha512-IYqDGiTXab6FniAgnSdZwgWbomxpy9FtYvLKs7wCUs2a8RkITG+DFGO1DM9cr+E3/RgADRpFjrKVaJ1z6sjtEg==}
|
||||
engines: {node: '>= 20.19.0'}
|
||||
|
||||
'@otplib/core@13.4.1':
|
||||
resolution: {integrity: sha512-KIXgK1hNtWJEBMTastbe1bpmuais+3f+ATeO8TkMs2rNkfGO1FbQy8+/UWVEu3TR/iTJerU0idkPudaPmLP2BA==}
|
||||
|
||||
'@otplib/hotp@13.4.1':
|
||||
resolution: {integrity: sha512-g9q04SwpG5ZtMnVkUcgcoAlwCH4YLROZN1qhyBwgkBzqYYVSYhpP6gSGaxGHwePLt1c+e6NqDlgIZN+e1/XPuA==}
|
||||
|
||||
'@otplib/plugin-base32-scure@13.4.1':
|
||||
resolution: {integrity: sha512-Fs/r5qisC05SRhT6xWXaypB6PVC0vgWf6zztmi0J5RnQ09OJiPDWCJFH6cDm6ANsrdvB9di7X+Jb7L13BoEbUA==}
|
||||
|
||||
'@otplib/plugin-crypto-noble@13.4.1':
|
||||
resolution: {integrity: sha512-PJfVW8/1hdS6CfxLheKPZSLTwDq4TijZbN4yRjxlv0ODdzmxpM+wGwWr1JXMdy0xJPxLziydQD5gdVqrR4/gAg==}
|
||||
|
||||
'@otplib/totp@13.4.1':
|
||||
resolution: {integrity: sha512-QOkBVPrf6AM4qZaReZPSk9/I8ATVdZpIISJz115MqeVtcrbcr5llPZ0J7804tpnjnp1vCRkI5Qjd47HhgVteBQ==}
|
||||
|
||||
'@otplib/uri@13.4.1':
|
||||
resolution: {integrity: sha512-xaIm7bvICMhoB2rZIR5luiaMdssWR5nY5nXnR1fdezUgZuEO58D6zrGzLp7pQuBmlpmL0HagnscDQFoskp9yiA==}
|
||||
|
||||
'@playwright/test@1.61.1':
|
||||
resolution: {integrity: sha512-8nKv6+0RJSL9FE4jYOEGXnPeM/Hg12qZpmqzZjRh3qM0Y7c3z1mrOTfFLids72RDQYVh9WpLEfR5WdpNX4fkig==}
|
||||
engines: {node: '>=18'}
|
||||
hasBin: true
|
||||
|
||||
'@scure/base@2.2.0':
|
||||
resolution: {integrity: sha512-b8XEupJibegiXV+tDUseI8oLQc8ei3d/4Jkb2RpbHh3MfE054ov3uIz2dhFkB3FI8iwYkEh0gGCApkrYggkPNg==}
|
||||
|
||||
'@types/node@26.1.1':
|
||||
resolution: {integrity: sha512-nxAkRSVkN1Y0JC1W8ky/fTfkGsMmcrRsbx+3XoZE+rMOX71kLYTV7fLXpqud1GpbpP5TuffXFqfX7fH2GgZREw==}
|
||||
|
||||
fsevents@2.3.2:
|
||||
resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
|
||||
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
|
||||
os: [darwin]
|
||||
|
||||
otplib@13.4.1:
|
||||
resolution: {integrity: sha512-o5CxfDw6bh7hoDv0NUUIcc0RqzJ9ipfUrzeKheKJ+vs4rXZnDlA9n4a/7R1cDjpmLjKLix4BgNVRmoDkm5rLSQ==}
|
||||
|
||||
playwright-core@1.61.1:
|
||||
resolution: {integrity: sha512-h7Qlt6m4REp25qvIdvbDtVmD4LqVXfpRxhORv9L0jzETM05p4fuPJ3dKyuSXQxDSbXnmS79HAgi9589lGSpLkg==}
|
||||
engines: {node: '>=18'}
|
||||
hasBin: true
|
||||
|
||||
playwright@1.61.1:
|
||||
resolution: {integrity: sha512-DWnY5o3YbLWK4GovuAVwpqL+1VwGNdUGrRr++8j8PtQQzvAVZUIMjKQ90fY689sEJZJBbZVw1rXaOKSTitkzPQ==}
|
||||
engines: {node: '>=18'}
|
||||
hasBin: true
|
||||
|
||||
undici-types@8.3.0:
|
||||
resolution: {integrity: sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==}
|
||||
|
||||
snapshots:
|
||||
|
||||
'@noble/hashes@2.2.0': {}
|
||||
|
||||
'@otplib/core@13.4.1': {}
|
||||
|
||||
'@otplib/hotp@13.4.1':
|
||||
dependencies:
|
||||
'@otplib/core': 13.4.1
|
||||
'@otplib/uri': 13.4.1
|
||||
|
||||
'@otplib/plugin-base32-scure@13.4.1':
|
||||
dependencies:
|
||||
'@otplib/core': 13.4.1
|
||||
'@scure/base': 2.2.0
|
||||
|
||||
'@otplib/plugin-crypto-noble@13.4.1':
|
||||
dependencies:
|
||||
'@noble/hashes': 2.2.0
|
||||
'@otplib/core': 13.4.1
|
||||
|
||||
'@otplib/totp@13.4.1':
|
||||
dependencies:
|
||||
'@otplib/core': 13.4.1
|
||||
'@otplib/hotp': 13.4.1
|
||||
'@otplib/uri': 13.4.1
|
||||
|
||||
'@otplib/uri@13.4.1':
|
||||
dependencies:
|
||||
'@otplib/core': 13.4.1
|
||||
|
||||
'@playwright/test@1.61.1':
|
||||
dependencies:
|
||||
playwright: 1.61.1
|
||||
|
||||
'@scure/base@2.2.0': {}
|
||||
|
||||
'@types/node@26.1.1':
|
||||
dependencies:
|
||||
undici-types: 8.3.0
|
||||
|
||||
fsevents@2.3.2:
|
||||
optional: true
|
||||
|
||||
otplib@13.4.1:
|
||||
dependencies:
|
||||
'@otplib/core': 13.4.1
|
||||
'@otplib/hotp': 13.4.1
|
||||
'@otplib/plugin-base32-scure': 13.4.1
|
||||
'@otplib/plugin-crypto-noble': 13.4.1
|
||||
'@otplib/totp': 13.4.1
|
||||
'@otplib/uri': 13.4.1
|
||||
|
||||
playwright-core@1.61.1: {}
|
||||
|
||||
playwright@1.61.1:
|
||||
dependencies:
|
||||
playwright-core: 1.61.1
|
||||
optionalDependencies:
|
||||
fsevents: 2.3.2
|
||||
|
||||
undici-types@8.3.0: {}
|
||||
@@ -0,0 +1,28 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import {LoginFixture, LogoutFixture} from "../fixtures/auth.fixtures";
|
||||
|
||||
test('should be able to login to app with forward-auth', async ({ page }) => {
|
||||
const loginFixture = new LoginFixture(page);
|
||||
await page.goto('http://whoami.127.0.0.1.sslip.io');
|
||||
// redirect to tinyauth
|
||||
await expect(page.getByText('Welcome back, please login')).toBeVisible()
|
||||
await loginFixture.run('user1', 'password')
|
||||
// redirect to app
|
||||
await expect(page.getByText('whoami.127.0.0.1.sslip.io')).toBeVisible()
|
||||
});
|
||||
|
||||
test('non authorized user should not be able to access app', async ({ page }) => {
|
||||
const loginFixture = new LoginFixture(page);
|
||||
await page.goto('http://whoami.127.0.0.1.sslip.io');
|
||||
// redirect to tinyauth
|
||||
await expect(page.getByText('Welcome back, please login')).toBeVisible()
|
||||
// user2 is not authorized to access app
|
||||
await loginFixture.run('user2', 'password')
|
||||
// redirect to app
|
||||
await expect(page.getByText('The user with username user2 is not authorized to access the resource whoami.')).toBeVisible()
|
||||
})
|
||||
|
||||
test('allowed path should skip authentication', async ({ page }) => {
|
||||
await page.goto('http://whoami.127.0.0.1.sslip.io/foo');
|
||||
await expect(page.getByText('whoami.127.0.0.1.sslip.io')).toBeVisible()
|
||||
})
|
||||
@@ -0,0 +1,48 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import {LoginFixture, LogoutFixture, TOTPFixture} from "../fixtures/auth.fixtures";
|
||||
|
||||
test('should be able to login', async ({ page }) => {
|
||||
const loginFixture = new LoginFixture(page);
|
||||
await page.goto('http://tinyauth.127.0.0.1.sslip.io');
|
||||
await loginFixture.run('user1', 'password')
|
||||
await loginFixture.expectSuccess('user1')
|
||||
});
|
||||
|
||||
test('should fail to login with wrong credentials', async ({ page }) => {
|
||||
const loginFixture = new LoginFixture(page);
|
||||
await page.goto('http://tinyauth.127.0.0.1.sslip.io');
|
||||
await loginFixture.run('user27267', 'password')
|
||||
const toast = page.locator('[data-sonner-toast]').first();
|
||||
await expect(toast).toBeVisible();
|
||||
await expect(toast).toContainText('Failed to log in');
|
||||
});
|
||||
|
||||
|
||||
test('should be able to logout', async ({ page }) => {
|
||||
const loginFixture = new LoginFixture(page);
|
||||
await page.goto('http://tinyauth.127.0.0.1.sslip.io');
|
||||
await loginFixture.run('user1', 'password')
|
||||
await loginFixture.expectSuccess('user1')
|
||||
const logoutFixture = new LogoutFixture(page);
|
||||
await logoutFixture.run()
|
||||
})
|
||||
|
||||
test('should be able to login with totp', async ({ page }) => {
|
||||
const loginFixture = new LoginFixture(page);
|
||||
const totpFixture = new TOTPFixture(page);
|
||||
await page.goto('http://tinyauth.127.0.0.1.sslip.io');
|
||||
await loginFixture.run('user3', 'password')
|
||||
await totpFixture.run('MVR4JQWNXYKNM6HHJEYEFP2O74QIIEJE')
|
||||
await loginFixture.expectSuccess('user3');
|
||||
});
|
||||
|
||||
test('should fail to login with wrong totp', async ({ page }) => {
|
||||
const loginFixture = new LoginFixture(page);
|
||||
const totpFixture = new TOTPFixture(page);
|
||||
await page.goto('http://tinyauth.127.0.0.1.sslip.io');
|
||||
await loginFixture.run('user3', 'password')
|
||||
await totpFixture.run('VZVMOMQCBN24DJ5VRFAL5TJAZGBHXMN3')
|
||||
const toast = page.locator('[data-sonner-toast]').first();
|
||||
await expect(toast).toBeVisible();
|
||||
await expect(toast).toContainText('Failed to verify code');
|
||||
});
|
||||
Reference in New Issue
Block a user