90 lines
2.4 KiB
TypeScript
90 lines
2.4 KiB
TypeScript
import { encode } from "@auth/core/jwt";
|
|
import { test as base, expect, type Page } from "@playwright/test";
|
|
|
|
import { prisma } from "$lib/server/prisma";
|
|
|
|
export const OIDC_BASE_URL = process.env.KEYCLOAK_ISSUER + "/";
|
|
const AUTH_COOKIE = "authjs.session-token";
|
|
|
|
type Account = {
|
|
id: number;
|
|
name: string;
|
|
email: string;
|
|
accessToken: string | null;
|
|
};
|
|
|
|
export async function isLoggedIn(page: Page): Promise<boolean> {
|
|
const cookies = await page.context().cookies();
|
|
return cookies.findIndex((c) => c.name === AUTH_COOKIE) !== -1;
|
|
}
|
|
|
|
async function newSessionToken(user: Account): Promise<string> {
|
|
return encode({
|
|
salt: AUTH_COOKIE,
|
|
secret: process.env.AUTH_SECRET!,
|
|
token: {
|
|
name: user.name,
|
|
email: user.email,
|
|
sub: user.id.toString(),
|
|
id: user.id.toString(),
|
|
accessToken: user.accessToken,
|
|
},
|
|
});
|
|
}
|
|
|
|
export const test = base.extend<object, {
|
|
account: Account,
|
|
}>({
|
|
account: [async ({ browser }, use, workerInfo) => {
|
|
// Unique username
|
|
const name = "user" + workerInfo.workerIndex;
|
|
const email = name + "@example.org";
|
|
|
|
// Create the account
|
|
const page = await browser.newPage();
|
|
await page.goto("/");
|
|
|
|
if (page.url().startsWith(OIDC_BASE_URL)) {
|
|
await page.locator('input[name="login"]').fill(name);
|
|
await page.locator('input[name="password"]').fill("1234");
|
|
await page.locator("button.login-submit").click();
|
|
await page.getByRole("button", { name: "Continue" }).click();
|
|
expect(await isLoggedIn(page)).toBe(true);
|
|
}
|
|
|
|
// Get user data
|
|
const user = await prisma.user.findUniqueOrThrow({
|
|
select: {
|
|
id: true,
|
|
accounts: {
|
|
select: { access_token: true },
|
|
where: { provider: "keycloak" },
|
|
},
|
|
},
|
|
where: { email },
|
|
});
|
|
expect(user.accounts.length).toBe(1);
|
|
|
|
// Use the account data when calling the fixture
|
|
await use({
|
|
id: user.id, name, email, accessToken: user.accounts[0].access_token,
|
|
});
|
|
}, { scope: "worker" }],
|
|
}).extend<{
|
|
login: Page,
|
|
}>({
|
|
login: async ({ page, account }, use) => {
|
|
const token = await newSessionToken(account);
|
|
await page.context().addCookies([{
|
|
name: AUTH_COOKIE,
|
|
value: token,
|
|
domain: "localhost",
|
|
path: "/",
|
|
httpOnly: true,
|
|
sameSite: "Lax",
|
|
}]);
|
|
await use(page);
|
|
},
|
|
});
|
|
|
|
export { expect } from "@playwright/test";
|