// A big PDF (a scanned volume of 400 pages, e2e/make_pdf.py): it opens at once, only the // pages near the view are drawn, the end can be reached, and opening can be cancelled. const path = require('path'); const { test, expect } = require('@playwright/test'); test.use({ storageState: path.join(__dirname, '.auth', 'user.json') }); test.describe.configure({ mode: 'serial' }); const PDF = path.join(__dirname, '.auth', 'big.pdf'); let bookId = null; let pageErrors = []; test.beforeEach(({ page }) => { pageErrors = []; page.on('pageerror', e => pageErrors.push(String(e))); }); test.afterEach(() => { expect(pageErrors, 'errors in the page').toEqual([]); }); async function ready(page) { await page.goto('/#books'); await page.waitForLoadState('networkidle'); await page.waitForFunction(() => typeof openBook === 'function' && Array.isArray(_lastBookListData)); } const drawn = page => page.evaluate(() => [...document.querySelectorAll('#reader-content canvas.pdf-page')].filter(c => c.width > 0).length); test('the big PDF goes in', async ({ page }) => { await ready(page); await page.locator('#book-file-input').setInputFiles(PDF); await page.waitForFunction(() => _lastBookListData.some(b => b.title === 'Dicker Band'), null, { timeout: 30000 }); bookId = await page.evaluate(() => _lastBookListData.find(b => b.title === 'Dicker Band').id); }); test('it opens with every page placed, only those near the view drawn', async ({ page }) => { await ready(page); await page.evaluate(id => openBook(id), bookId); await page.waitForFunction(() => _readPos && _readPos.ready, null, { timeout: 20000 }); await expect(page.locator('#reader-content .pdf-page-wrapper')).toHaveCount(400); await expect(page.locator('.pdf-loading-overlay')).toHaveCount(0); await expect.poll(() => drawn(page)).toBeGreaterThan(0); expect(await drawn(page)).toBeLessThan(30); // To the end: the last page gets drawn, the first ones are let go. await page.evaluate(() => { const c = document.getElementById('reader-content'); c.scrollTop = c.scrollHeight; }); await expect.poll(() => page.evaluate(() => document.querySelector('#pdf-page-400 canvas').width > 0)).toBe(true); await expect.poll(() => page.evaluate(() => document.querySelector('#pdf-page-1 canvas').width)).toBe(0); expect(await drawn(page)).toBeLessThan(30); await page.evaluate(() => closeReader()); }); test('opening can be cancelled, and another book opens after it', async ({ page }) => { await ready(page); // Slow the file down so the opening is still under way. await page.route(`**/books/${bookId}/data/`, async route => { await new Promise(r => setTimeout(r, 1500)); await route.continue().catch(() => {}); }); const p = page.evaluate(id => openBook(id).then(() => 'done', e => 'error ' + e), bookId); await expect(page.locator('.reader-opening-cancel')).toBeVisible({ timeout: 5000 }); await page.locator('.reader-opening-cancel').click(); await expect(page.locator('#reader-overlay')).toBeHidden(); expect(await p).toBe('done'); await page.unroute(`**/books/${bookId}/data/`); // Opening it again works, all the way. await page.evaluate(id => openBook(id), bookId); await page.waitForFunction(() => _readPos && _readPos.ready, null, { timeout: 20000 }); await page.evaluate(() => closeReader()); await page.request.post(`/books/${bookId}/delete/`); });