Files
computer-playbook/roles/web-app-fediwall/files/playwright/test-walls-surface-posts.js

90 lines
3.6 KiB
JavaScript

const { test, expect } = require("@playwright/test");
const { resolveTimeout } = require("./timeouts");
// Cross-Fediverse scenario — runs whenever Mastodon AND Friendica are
// deployed alongside fediwall. The test is fully data-driven against
// each wall's `wall-config.json` `servers` list:
//
// - biber posts a unique status to BOTH Mastodon and Friendica via
// the same SSO/ldapauth UI flow a human would use (LDAP is the
// single source of truth for biber's credentials; the local
// accounts on Mastodon/Friendica come into existence lazily on
// first SSO login, exactly as in production — no API auth, no
// password duplication, no manual user provisioning).
//
// - For every deployed wall, the test reads `wall-config.json`
// and asserts: a sibling's post is visible iff that sibling's
// domain is listed in `servers`; otherwise it MUST NOT appear.
//
// This single test covers both variants automatically:
// variant 0 — one wall polling all active siblings (both posts visible)
// variant 1 — two walls; one polls both siblings, the other only
// Mastodon (friendica post must be absent there).
exports.register = function (shared) {
test("each wall surfaces biber's posts according to its servers list", async ({
browser,
request,
}) => {
shared.skipUnlessServiceEnabled("mastodon");
shared.skipUnlessServiceEnabled("friendica");
const stamp = Date.now();
// Driver per source app: how to post + which host the wall config
// would list when this sibling is enabled.
const siblings = [
{
name: "mastodon",
host: shared.urlHost(shared.env.mastodonBaseUrl),
status: `fediwall-e2e mastodon ${stamp}`,
post: (page) => shared.postOnMastodonViaUi(page, shared.env.mastodonBaseUrl, `fediwall-e2e mastodon ${stamp}`),
},
{
name: "friendica",
host: shared.urlHost(shared.env.friendicaBaseUrl),
status: `fediwall-e2e friendica ${stamp}`,
post: (page) => shared.postOnFriendicaViaUi(page, shared.env.friendicaBaseUrl, `fediwall-e2e friendica ${stamp}`),
},
];
// Post once per sibling — isolated browser contexts so the OIDC
// session for Mastodon and the ldapauth session for Friendica do
// not bleed cookies/storage across.
for (const s of siblings) {
const ctx = await browser.newContext({ ignoreHTTPSErrors: true });
try {
await s.post(await ctx.newPage());
} finally {
await ctx.close().catch(() => {});
}
}
// For every deployed wall: read its servers list and assert that
// each sibling's post appears iff its host is in `servers`.
for (const slug of shared.env.wallSlugs) {
const cfgRes = await request.get(`${shared.env.appBaseUrl}/${slug}/wall-config.json`, { timeout: resolveTimeout(30_000) });
expect(
cfgRes.ok(),
`wall-config.json for slug='${slug}' must be reachable`
).toBeTruthy();
const cfg = await cfgRes.json();
const wallHosts = new Set(cfg.servers || []);
const wallCtx = await browser.newContext({ ignoreHTTPSErrors: true });
try {
const wallPage = await wallCtx.newPage();
for (const s of siblings) {
const wallUrl = `${shared.env.appBaseUrl}/${slug}/`;
if (wallHosts.has(s.host)) {
await shared.expectPostVisibleOnWall(wallPage, wallUrl, s.status);
} else {
await shared.expectPostAbsentFromWall(wallPage, wallUrl, s.status);
}
}
} finally {
await wallCtx.close().catch(() => {});
}
}
});
};