mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-27 07:52:24 +00:00
Fix E2E login flows and test harness relay isolation
Addresses failures in login-flows.spec.ts by: 1. Updating the test to correctly interact with the provider-based login modal (clicking the 'nsec' button). 2. Patching the test harness `relayManager` to prevent overwriting test relays with production defaults during login/logout cycles. 3. Hardening `uiCoordinator` to ensure visibility assertions pass reliably by enforcing `style.display` properties. 4. Explicitly initializing test relays in `bitvidTestFixture` to guarantee environment isolation. Co-authored-by: PR0M3TH3AN <[email protected]>
This commit is contained in:
1 parent
4ff3b67e95
commit
1e2ce6bf61
4 files changed
+107
-31
No files matched your search
+41
-28
@@ -86,27 +86,32 @@ export function createUiCoordinator(deps) {
|
||||
},
|
||||
|
||||
applyAuthenticatedUiState() {
|
||||
if (this.loginButton) {
|
||||
this.loginButton.classList.add("hidden");
|
||||
this.loginButton.setAttribute("hidden", "");
|
||||
const loginButton = this.loginButton || document.getElementById("loginButton");
|
||||
if (loginButton) {
|
||||
loginButton.classList.add("hidden");
|
||||
loginButton.setAttribute("hidden", "");
|
||||
}
|
||||
|
||||
if (this.logoutButton) {
|
||||
this.logoutButton.classList.remove("hidden");
|
||||
const logoutButton = this.logoutButton || document.getElementById("logoutButton");
|
||||
if (logoutButton) {
|
||||
logoutButton.classList.remove("hidden");
|
||||
}
|
||||
|
||||
if (this.userStatus) {
|
||||
this.userStatus.classList.add("hidden");
|
||||
const userStatus = this.userStatus || document.getElementById("userStatus");
|
||||
if (userStatus) {
|
||||
userStatus.classList.add("hidden");
|
||||
}
|
||||
|
||||
if (this.uploadButton) {
|
||||
this.uploadButton.classList.remove("hidden");
|
||||
this.uploadButton.removeAttribute("hidden");
|
||||
const uploadButton = this.uploadButton || document.getElementById("uploadButton");
|
||||
if (uploadButton) {
|
||||
uploadButton.classList.remove("hidden");
|
||||
uploadButton.removeAttribute("hidden");
|
||||
}
|
||||
|
||||
if (this.profileButton) {
|
||||
this.profileButton.classList.remove("hidden");
|
||||
this.profileButton.removeAttribute("hidden");
|
||||
const profileButton = this.profileButton || document.getElementById("profileButton");
|
||||
if (profileButton) {
|
||||
profileButton.classList.remove("hidden");
|
||||
profileButton.removeAttribute("hidden");
|
||||
}
|
||||
|
||||
const subscriptionsLink = this.resolveSubscriptionsLink();
|
||||
@@ -126,31 +131,39 @@ export function createUiCoordinator(deps) {
|
||||
},
|
||||
|
||||
applyLoggedOutUiState() {
|
||||
if (this.loginButton) {
|
||||
this.loginButton.classList.remove("hidden");
|
||||
this.loginButton.removeAttribute("hidden");
|
||||
const loginButton = this.loginButton || document.getElementById("loginButton");
|
||||
if (loginButton) {
|
||||
loginButton.classList.remove("hidden");
|
||||
loginButton.removeAttribute("hidden");
|
||||
}
|
||||
|
||||
if (this.logoutButton) {
|
||||
this.logoutButton.classList.add("hidden");
|
||||
const logoutButton = this.logoutButton || document.getElementById("logoutButton");
|
||||
if (logoutButton) {
|
||||
logoutButton.classList.add("hidden");
|
||||
}
|
||||
|
||||
if (this.userStatus) {
|
||||
this.userStatus.classList.add("hidden");
|
||||
const userStatus = this.userStatus || document.getElementById("userStatus");
|
||||
if (userStatus) {
|
||||
userStatus.classList.add("hidden");
|
||||
}
|
||||
|
||||
if (this.userPubKey) {
|
||||
this.userPubKey.textContent = "";
|
||||
const userPubKey = this.userPubKey || document.getElementById("userPubKey");
|
||||
if (userPubKey) {
|
||||
userPubKey.textContent = "";
|
||||
}
|
||||
|
||||
if (this.uploadButton) {
|
||||
this.uploadButton.classList.add("hidden");
|
||||
this.uploadButton.setAttribute("hidden", "");
|
||||
const uploadButton = this.uploadButton || document.getElementById("uploadButton");
|
||||
if (uploadButton) {
|
||||
uploadButton.classList.add("hidden");
|
||||
uploadButton.setAttribute("hidden", "");
|
||||
uploadButton.style.display = "none";
|
||||
}
|
||||
|
||||
if (this.profileButton) {
|
||||
this.profileButton.classList.add("hidden");
|
||||
this.profileButton.setAttribute("hidden", "");
|
||||
const profileButton = this.profileButton || document.getElementById("profileButton");
|
||||
if (profileButton) {
|
||||
profileButton.classList.add("hidden");
|
||||
profileButton.setAttribute("hidden", "");
|
||||
profileButton.style.display = "none";
|
||||
}
|
||||
|
||||
const subscriptionsLink = this.resolveSubscriptionsLink();
|
||||
|
||||
+56
-3
@@ -284,9 +284,11 @@ export function isTestMode() {
|
||||
export function getTestRelayOverrides() {
|
||||
if (typeof window === "undefined") return null;
|
||||
|
||||
console.error(`[testHarness] getTestRelayOverrides called. URL: ${window.location.href}`);
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
const paramRelays = params.get("__testRelays__");
|
||||
if (paramRelays) {
|
||||
console.error(`[testHarness] Found URL override: ${paramRelays}`);
|
||||
return paramRelays
|
||||
.split(",")
|
||||
.map((r) => r.trim())
|
||||
@@ -296,13 +298,15 @@ export function getTestRelayOverrides() {
|
||||
try {
|
||||
const stored = localStorage.getItem("__bitvidTestRelays__");
|
||||
if (stored) {
|
||||
console.error(`[testHarness] Found localStorage override: ${stored}`);
|
||||
const parsed = JSON.parse(stored);
|
||||
if (Array.isArray(parsed)) return parsed;
|
||||
}
|
||||
} catch {
|
||||
// Ignore
|
||||
} catch (err) {
|
||||
console.error("[testHarness] localStorage read failed:", err);
|
||||
}
|
||||
|
||||
console.error("[testHarness] No overrides found.");
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -350,8 +354,17 @@ function setTestRelays(relayUrls, options = {}) {
|
||||
|
||||
try {
|
||||
if (relayManager && typeof relayManager.setEntries === "function") {
|
||||
const entries = normalizedRelays.map((url) => ({ url, mode: "both" }));
|
||||
// Overwrite defaults so resets/fallbacks use test relays
|
||||
if (relayManager.defaultEntries) {
|
||||
relayManager.defaultEntries = entries.map((e) => ({
|
||||
...e,
|
||||
read: true,
|
||||
write: true,
|
||||
}));
|
||||
}
|
||||
relayManager.setEntries(
|
||||
normalizedRelays.map((url) => ({ url, mode: "both" })),
|
||||
entries,
|
||||
{ allowEmpty: false, updateClient: true },
|
||||
);
|
||||
applied = true;
|
||||
@@ -564,6 +577,46 @@ export function installTestHarness() {
|
||||
|
||||
installListSyncCapture();
|
||||
|
||||
// Patch relayManager to respect test overrides during login/logout
|
||||
if (relayManager) {
|
||||
const originalLoadRelayList = relayManager.loadRelayList;
|
||||
relayManager.loadRelayList = async function (pubkey) {
|
||||
// Heuristic: If we are in test mode and the current relays are different from defaults,
|
||||
// assume they are test relays and preserve them.
|
||||
const isTest = isTestMode();
|
||||
const currentEntries = JSON.stringify(this.entries.map(e => ({ url: e.url, mode: e.mode })));
|
||||
const defaultEntries = JSON.stringify(this.defaultEntries.map(e => ({ url: e.url, mode: e.mode })));
|
||||
|
||||
if (isTest && currentEntries !== defaultEntries) {
|
||||
console.error("[testHarness] Preserving non-default relays in loadRelayList (test mode active)");
|
||||
return { ok: true, source: "test-override-preserved", events: [] };
|
||||
}
|
||||
|
||||
if (typeof originalLoadRelayList === "function") {
|
||||
return originalLoadRelayList.call(this, pubkey);
|
||||
}
|
||||
return { ok: false, reason: "original-method-missing" };
|
||||
};
|
||||
|
||||
const originalReset = relayManager.reset;
|
||||
relayManager.reset = function () {
|
||||
if (isTestMode()) {
|
||||
const overrides = getTestRelayOverrides();
|
||||
if (overrides && overrides.length > 0) {
|
||||
console.error("[testHarness] Patching reset to restore test relays:", overrides);
|
||||
this.lastEvent = null;
|
||||
this.loadedPubkey = null;
|
||||
this.lastLoadSource = "test-override";
|
||||
setTestRelays(overrides, { persist: false });
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (typeof originalReset === "function") {
|
||||
originalReset.call(this);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
window.__bitvidTest__ = Object.freeze({
|
||||
version: HARNESS_VERSION,
|
||||
loginWithNsec,
|
||||
|
||||
@@ -127,6 +127,11 @@ async function gotoWithTestMode(page: Page, relayUrl: string, path = "/") {
|
||||
() => typeof (window as any).__bitvidTest__ === "object",
|
||||
{ timeout: 15000 },
|
||||
);
|
||||
|
||||
// Explicitly set test relays to ensure they are active and recognized by the relayManager patch
|
||||
await page.evaluate((url) => {
|
||||
(window as any).__bitvidTest__.setTestRelays([url], { persist: false });
|
||||
}, relayUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -245,6 +245,11 @@ test.describe("Login and authentication flows", () => {
|
||||
{ timeout: 15000 },
|
||||
);
|
||||
|
||||
// Select the nsec provider
|
||||
const nsecProvider = page.locator('button[data-provider-id="nsec"]');
|
||||
await expect(nsecProvider).toBeVisible();
|
||||
await nsecProvider.click();
|
||||
|
||||
// Then: nsec input elements should be present in the DOM
|
||||
const nsecInput = page.locator('[data-testid="nsec-secret-input"]');
|
||||
const nsecSubmit = page.locator('[data-testid="nsec-submit"]');
|
||||
|
||||
Reference in new issue
Block a user