feat(private-zone): default to albums tab
Docker Image / Build and Push Docker Image (push) Successful in 2m17s

(cherry picked from commit a2cf62f78b)
This commit is contained in:
Codex
2026-07-27 18:55:58 +08:00
parent 9f829bbc0e
commit d5b7a1f36c
3 changed files with 37 additions and 19 deletions
+5 -5
View File
@@ -107,13 +107,14 @@ for (const character of characters) {
await page.goto(`/characters/${character.slug}/private-zone`); await page.goto(`/characters/${character.slug}/private-zone`);
await Promise.all([momentsRequest, albumRequest]); await Promise.all([momentsRequest, albumRequest]);
await expect(
page.getByRole("heading", { name: "Private moments" }),
).toBeVisible();
await page.getByRole("tab", { name: "Albums" }).click();
await expect( await expect(
page.getByRole("heading", { name: "Private albums" }), page.getByRole("heading", { name: "Private albums" }),
).toBeVisible(); ).toBeVisible();
await expect(page.getByRole("tab")).toHaveText(["Albums", "Moments"]);
await expect(page.getByRole("tab", { name: "Albums" })).toHaveAttribute(
"aria-selected",
"true",
);
await expect(page.getByText(character.displayName).last()).toBeVisible(); await expect(page.getByText(character.displayName).last()).toBeVisible();
const albumButton = page.getByRole("button", { const albumButton = page.getByRole("button", {
name: `View locked collection with 8 images from ${character.displayName}`, name: `View locked collection with 8 images from ${character.displayName}`,
@@ -163,7 +164,6 @@ test("a real Private Zone request failure still offers Retry", async ({
await page.goto("/characters/maya/private-zone"); await page.goto("/characters/maya/private-zone");
await page.getByRole("tab", { name: "Albums" }).click();
await expect(page.getByRole("button", { name: "Retry" })).toBeVisible(); await expect(page.getByRole("button", { name: "Retry" })).toBeVisible();
await expect(page.getByRole("button", { name: "Refresh" })).toHaveCount(0); await expect(page.getByRole("button", { name: "Refresh" })).toHaveCount(0);
}); });
+22 -4
View File
@@ -17,7 +17,7 @@ test.beforeEach(async ({ baseURL, context, page }) => {
await registerPrivateZoneVideoMocks(page); await registerPrivateZoneVideoMocks(page);
}); });
test("Private Zone defaults to Moments and reveals video only after one credit unlock", async ({ test("Private Zone defaults to Albums and reveals video after switching to Moments", async ({
page, page,
}) => { }) => {
await seedEmailSession(page); await seedEmailSession(page);
@@ -32,6 +32,11 @@ test("Private Zone defaults to Moments and reveals video only after one credit u
await page.goto("/characters/maya/private-zone"); await page.goto("/characters/maya/private-zone");
await listRequest; await listRequest;
await expect(
page.getByRole("heading", { name: "Private albums" }),
).toBeVisible();
await expect(page.getByText("Maya archive")).toBeVisible();
await page.getByRole("tab", { name: "Moments" }).click();
await expect( await expect(
page.getByRole("heading", { name: "Private moments" }), page.getByRole("heading", { name: "Private moments" }),
).toBeVisible(); ).toBeVisible();
@@ -53,16 +58,29 @@ test("Private Zone defaults to Moments and reveals video only after one credit u
await expect(page.getByRole("alertdialog")).toHaveCount(0); await expect(page.getByRole("alertdialog")).toHaveCount(0);
}); });
test("Albums remain available behind the second tab", async ({ page }) => { test("Albums render first and Moments remain available behind the second tab", async ({ page }) => {
await seedEmailSession(page); await seedEmailSession(page);
await page.goto("/characters/maya/private-zone"); await page.goto("/characters/maya/private-zone");
await page.getByRole("tab", { name: "Albums" }).click(); const tabs = page.getByRole("tab");
await expect(tabs).toHaveText(["Albums", "Moments"]);
await expect(page.getByRole("tab", { name: "Albums" })).toHaveAttribute(
"aria-selected",
"true",
);
await expect( await expect(
page.getByRole("heading", { name: "Private albums" }), page.getByRole("heading", { name: "Private albums" }),
).toBeVisible(); ).toBeVisible();
await expect(page.getByText("Maya archive")).toBeVisible(); await expect(page.getByText("Maya archive")).toBeVisible();
await page.getByRole("tab", { name: "Moments" }).click();
await expect(page.getByRole("tab", { name: "Moments" })).toHaveAttribute(
"aria-selected",
"true",
);
await expect(
page.getByRole("heading", { name: "Private moments" }),
).toBeVisible();
}); });
async function registerPrivateZoneVideoMocks(page: Page): Promise<void> { async function registerPrivateZoneVideoMocks(page: Page): Promise<void> {
+10 -10
View File
@@ -63,7 +63,7 @@ export function PrivateZoneScreen() {
const dispatch = usePrivateZoneDispatch(); const dispatch = usePrivateZoneDispatch();
const postState = usePrivateZonePostState(); const postState = usePrivateZonePostState();
const postDispatch = usePrivateZonePostDispatch(); const postDispatch = usePrivateZonePostDispatch();
const [activeTab, setActiveTab] = useState<"moments" | "albums">("moments"); const [activeTab, setActiveTab] = useState<"moments" | "albums">("albums");
const openedGalleryInPageRef = useRef(false); const openedGalleryInPageRef = useRef(false);
const previousPostLoginStatusRef = useRef(authState.loginStatus); const previousPostLoginStatusRef = useRef(authState.loginStatus);
const galleryState = useMemo( const galleryState = useMemo(
@@ -313,15 +313,6 @@ export function PrivateZoneScreen() {
<section className={styles.postsSection} aria-labelledby="posts-title"> <section className={styles.postsSection} aria-labelledby="posts-title">
<div className={styles.contentTabs} role="tablist" aria-label="Private Zone content"> <div className={styles.contentTabs} role="tablist" aria-label="Private Zone content">
<button
type="button"
role="tab"
aria-selected={visibleTab === "moments"}
className={`${styles.contentTab} ${visibleTab === "moments" ? styles.contentTabActive : ""}`}
onClick={() => setActiveTab("moments")}
>
Moments
</button>
<button <button
type="button" type="button"
role="tab" role="tab"
@@ -331,6 +322,15 @@ export function PrivateZoneScreen() {
> >
Albums Albums
</button> </button>
<button
type="button"
role="tab"
aria-selected={visibleTab === "moments"}
className={`${styles.contentTab} ${visibleTab === "moments" ? styles.contentTabActive : ""}`}
onClick={() => setActiveTab("moments")}
>
Moments
</button>
</div> </div>
<div className={styles.sectionHeader}> <div className={styles.sectionHeader}>