mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-06 10:59:59 +00:00
80 lines
3.4 KiB
JavaScript
80 lines
3.4 KiB
JavaScript
const { test, expect } = require("@playwright/test");
|
|
|
|
const { safeSkipUnlessEnabled, gotoOnion, recordVideoOptions } = require("./personas");
|
|
const { roundcubeSsoLogin, roundcubeLogout, sendMail, waitForEmailInMailbox } = require("./webmail");
|
|
const {
|
|
webmailBaseUrl,
|
|
adminEmail,
|
|
adminUsername,
|
|
adminPassword,
|
|
biberEmail,
|
|
biberUsername,
|
|
biberPassword,
|
|
} = require("./env");
|
|
const { resolveTimeout, isSplitRealmOidc } = require("./timeouts");
|
|
|
|
/** Open a delivered message and confirm its body renders. */
|
|
async function openMail(page, subject) {
|
|
const row = await waitForEmailInMailbox(page, webmailBaseUrl, subject, resolveTimeout(90_000));
|
|
await expect(row).toBeVisible();
|
|
await row.click();
|
|
await expect(
|
|
page.locator("#messagecontframe, #mailview-right, .message-part").first()
|
|
).toBeVisible({ timeout: resolveTimeout(15_000) });
|
|
}
|
|
|
|
async function leaveOpenDialogs(page) {
|
|
await gotoOnion(page, `${webmailBaseUrl}/?_task=mail&_mbox=INBOX`);
|
|
await page
|
|
.locator(".ui-widget-overlay")
|
|
.first()
|
|
.waitFor({ state: "detached", timeout: resolveTimeout(15_000) })
|
|
.catch(() => {});
|
|
}
|
|
|
|
// biber <-> administrator round trip through the Roundcube webmail UI: biber writes to
|
|
// the administrator, the administrator reads it and writes back, and biber reads the
|
|
// answer. Login is via Keycloak SSO (Roundcube XOAUTH2 -> Stalwart), mirroring
|
|
// web-app-mailu. They are separate people: isolated browser contexts, and biber stays
|
|
// signed in so the answer lands in a session that never saw the outbound message.
|
|
test("stalwart: biber and the administrator exchange mail both ways", async ({ browser }, testInfo) => {
|
|
test.skip(isSplitRealmOidc(), "clearnet app with an onion OIDC issuer: unreachable from one browser");
|
|
safeSkipUnlessEnabled("sso");
|
|
expect(webmailBaseUrl, "WEBMAIL_BASE_URL must be set").toBeTruthy();
|
|
expect(adminEmail, "ADMIN_EMAIL must be set").toBeTruthy();
|
|
expect(biberEmail, "BIBER_EMAIL must be set").toBeTruthy();
|
|
expect(biberPassword, "BIBER_PASSWORD must be set").toBeTruthy();
|
|
expect(adminPassword, "ADMIN_PASSWORD must be set").toBeTruthy();
|
|
|
|
const outbound = `Playwright stalwart ${Date.now()}`;
|
|
const answer = `Playwright stalwart answer ${Date.now()}`;
|
|
const proxyServer = process.env.PLAYWRIGHT_PROXY;
|
|
const contextOptions = {
|
|
ignoreHTTPSErrors: true,
|
|
...(proxyServer ? { proxy: { server: proxyServer } } : {}),
|
|
...recordVideoOptions(testInfo),
|
|
};
|
|
const biberContext = await browser.newContext(contextOptions);
|
|
const adminContext = await browser.newContext(contextOptions);
|
|
|
|
try {
|
|
const biberPage = await biberContext.newPage();
|
|
await roundcubeSsoLogin(biberPage, biberUsername, biberPassword);
|
|
await sendMail(biberPage, adminEmail, outbound, "Hello Administrator, this is an automated Playwright test email.");
|
|
|
|
const adminPage = await adminContext.newPage();
|
|
await roundcubeSsoLogin(adminPage, adminUsername, adminPassword);
|
|
await openMail(adminPage, outbound);
|
|
await leaveOpenDialogs(adminPage);
|
|
await sendMail(adminPage, biberEmail, answer, "Answer from the administrator, sent by the same Playwright run.");
|
|
await roundcubeLogout(adminPage);
|
|
|
|
await openMail(biberPage, answer);
|
|
await leaveOpenDialogs(biberPage);
|
|
await roundcubeLogout(biberPage);
|
|
} finally {
|
|
await biberContext.close().catch(() => {});
|
|
await adminContext.close().catch(() => {});
|
|
}
|
|
});
|