Merge branch 'feat/desktop-reader-brightness' into chore/reconcile-ui-review
This commit is contained in:
@@ -66,6 +66,15 @@ async function mockReaderApis(page: Page) {
|
||||
body: JSON.stringify({ error: { code: 'unauthenticated', message: '' } })
|
||||
})
|
||||
);
|
||||
// Anonymous reader: read-progress reads/writes are unauthenticated. Without
|
||||
// this the GET/PUT fall through to the (absent) backend and stall the load.
|
||||
await page.route('**/api/v1/me/read-progress/**', (route) =>
|
||||
route.fulfill({
|
||||
status: 401,
|
||||
contentType: 'application/json',
|
||||
body: JSON.stringify({ error: { code: 'unauthenticated', message: '' } })
|
||||
})
|
||||
);
|
||||
await page.route(`**/api/v1/mangas/${mangaId}`, (route) =>
|
||||
route.fulfill({
|
||||
status: 200,
|
||||
@@ -126,6 +135,7 @@ test.beforeEach(async ({ context }) => {
|
||||
try {
|
||||
localStorage.removeItem('mangalord-reader-mode');
|
||||
localStorage.removeItem('mangalord-reader-gap');
|
||||
localStorage.removeItem('mangalord-reader-brightness');
|
||||
} catch {
|
||||
// ignore — about:blank doesn't expose localStorage yet.
|
||||
}
|
||||
@@ -181,6 +191,64 @@ test('gap select updates the inline gap on the continuous container', async ({ p
|
||||
await expect(container).toHaveAttribute('style', /gap:\s*64px/);
|
||||
});
|
||||
|
||||
test('desktop reader nav exposes a brightness control that dims and undims the reader', async ({
|
||||
page
|
||||
}) => {
|
||||
// The brightness slider used to live only in the mobile settings sheet,
|
||||
// so desktop users couldn't dim — and could be stuck dimmed by a value a
|
||||
// phone had persisted. The desktop nav now carries its own slider.
|
||||
await mockReaderApis(page);
|
||||
await page.goto(`/manga/${mangaId}/chapter/${chapterId}`);
|
||||
|
||||
const slider = page.getByTestId('reader-brightness-desktop');
|
||||
await expect(slider).toBeVisible();
|
||||
|
||||
const dim = () =>
|
||||
page.evaluate(() =>
|
||||
document.documentElement.style.getPropertyValue('--reader-dim')
|
||||
);
|
||||
|
||||
// Default brightness is full → no dim overlay.
|
||||
await expect.poll(async () => Number(await dim())).toBe(0);
|
||||
|
||||
// Dimming raises the overlay opacity…
|
||||
await slider.fill('0.3');
|
||||
await expect.poll(async () => Number(await dim())).toBeGreaterThan(0);
|
||||
|
||||
// …and restoring it clears the dim, so a desktop user is never stuck.
|
||||
await slider.fill('1');
|
||||
await expect.poll(async () => Number(await dim())).toBe(0);
|
||||
});
|
||||
|
||||
test('a brightness value persisted by a phone is recoverable on desktop', async ({
|
||||
page,
|
||||
context
|
||||
}) => {
|
||||
// Seed a dimmed value as if set on mobile, then open the reader on a
|
||||
// desktop viewport: the dim applies and the desktop control reflects it.
|
||||
await context.addInitScript(() => {
|
||||
try {
|
||||
localStorage.setItem('mangalord-reader-brightness', '0.3');
|
||||
} catch {
|
||||
// about:blank — ignore
|
||||
}
|
||||
});
|
||||
await mockReaderApis(page);
|
||||
await page.goto(`/manga/${mangaId}/chapter/${chapterId}`);
|
||||
|
||||
const slider = page.getByTestId('reader-brightness-desktop');
|
||||
await expect(slider).toHaveValue('0.3');
|
||||
await expect
|
||||
.poll(async () =>
|
||||
Number(
|
||||
await page.evaluate(() =>
|
||||
document.documentElement.style.getPropertyValue('--reader-dim')
|
||||
)
|
||||
)
|
||||
)
|
||||
.toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
test('reader-mode preference set on one page is honored when the reader opens', async ({
|
||||
page,
|
||||
context
|
||||
|
||||
Reference in New Issue
Block a user