Download app/tests/column-resizer.mjs from Mike0021/MiniCPM5-2B-WebGPU-Pi-HTTP: direct link, hf CLI and curl.
- Browser
- Download file 7.76 kB
-
https://huggingface.co/spaces/Mike0021/MiniCPM5-2B-WebGPU-Pi-HTTP/resolve/main/app/tests/column-resizer.mjs
- Command line
-
hf download hf://spaces/Mike0021/MiniCPM5-2B-WebGPU-Pi-HTTP/app/tests/column-resizer.mjs
-
curl -L -o column-resizer.mjs https://huggingface.co/spaces/Mike0021/MiniCPM5-2B-WebGPU-Pi-HTTP/resolve/main/app/tests/column-resizer.mjs
7.76 kB
| import { chromium } from 'playwright'; | |
| import assert from 'node:assert/strict'; | |
| import fs from 'node:fs/promises'; | |
| const url = process.argv[2] ?? 'http://127.0.0.1:4173/'; | |
| const result = { url, checks: [], errors: [] }; | |
| const browser = await chromium.launch({ executablePath: '/usr/bin/chromium', headless: true }); | |
| const page = await browser.newPage({ viewport: { width: 1440, height: 1000 } }); | |
| page.setDefaultTimeout(15000); | |
| page.on('pageerror', error => result.errors.push(error.message)); | |
| const ready = async () => { await page.waitForFunction(() => window.browserPi?.terminal); await page.evaluate(() => window.browserPi.ready); }; | |
| const divider = page.getByRole('separator', { name: 'Resize chat and workspace' }); | |
| const geometry = async () => { | |
| const size = await page.evaluate(() => { | |
| const rect = selector => document.querySelector(selector).getBoundingClientRect().toJSON(); | |
| return { main: rect('main'), chat: rect('.conversation'), workspace: rect('.workspace'), handle: rect('#column-resizer'), | |
| desktop: matchMedia('(min-width: 851px)').matches, | |
| gutter: parseFloat(getComputedStyle(document.querySelector('main')).getPropertyValue('--content-gutter')), | |
| cols: window.browserPi.terminal.cols, overflow: document.documentElement.scrollWidth > innerWidth }; | |
| }); | |
| if (size.desktop) { | |
| closeTo(size.workspace.left, size.chat.right); | |
| closeTo(size.workspace.right + size.gutter, size.main.right); | |
| } | |
| return size; | |
| }; | |
| const frames = () => page.evaluate(() => new Promise(resolve => requestAnimationFrame(() => requestAnimationFrame(resolve)))); | |
| async function drag(delta, release = true) { | |
| const r = await divider.boundingBox(); | |
| await page.mouse.move(r.x + r.width / 2, r.y + r.height / 2); await page.mouse.down(); | |
| await page.mouse.move(r.x + r.width / 2 + delta, r.y + r.height / 2, { steps: 12 }); | |
| if (release) await page.mouse.up(); | |
| await frames(); | |
| } | |
| const closeTo = (actual, expected) => assert(Math.abs(actual - expected) < 1, `${actual} vs ${expected}`); | |
| try { | |
| await page.goto(url); await ready(); | |
| assert(await divider.isVisible()); | |
| const initial = await geometry(); | |
| closeTo(initial.chat.width, initial.main.width / 1.83); | |
| assert(initial.handle.x >= initial.chat.right - 14.1 && initial.handle.right <= initial.workspace.left + .1); | |
| await page.locator('.xterm-helper-textarea').focus(); | |
| await page.keyboard.type('Keep this draft'); await page.keyboard.press('Shift+Enter'); await page.keyboard.type('while resizing'); | |
| await page.locator('#files button[title="/workspace/products.json"]').click(); | |
| await page.locator('#editor').fill('{"unsaved": true}'); | |
| await page.locator('#command').fill('echo "unsent command"'); | |
| await drag(240); | |
| assert((await geometry()).chat.width > initial.chat.width + 230); | |
| await page.waitForFunction(cols => window.browserPi.terminal.cols > cols, initial.cols); | |
| assert.equal(await page.evaluate(() => window.browserPi.terminal.text), 'Keep this draft\nwhile resizing'); | |
| assert.equal(await page.locator('#editor').inputValue(), '{"unsaved": true}'); | |
| assert.equal(await page.locator('#command').inputValue(), 'echo "unsent command"'); | |
| assert(await page.locator('#save').isEnabled()); | |
| await page.waitForFunction(() => document.querySelector('#editor-highlight').clientWidth === document.querySelector('#editor').clientWidth); | |
| result.checks.push('Live resizing preserves Pi, file and shell drafts and resizes the terminal and syntax layer'); | |
| await drag(-2000); closeTo((await geometry()).chat.width, 420); | |
| await divider.press('End'); await frames(); | |
| let size = await geometry(); closeTo(size.main.width - size.chat.width, 370); | |
| assert.equal(await divider.getAttribute('aria-valuenow'), await divider.getAttribute('aria-valuemax')); | |
| await divider.press('ArrowLeft'); await frames(); closeTo((await geometry()).chat.width, size.chat.width - 16); | |
| await divider.press('Shift+ArrowLeft'); await frames(); closeTo((await geometry()).chat.width, size.chat.width - 64); | |
| await divider.press('Home'); await frames(); closeTo((await geometry()).chat.width, 420); | |
| await divider.press('Enter'); await frames(); closeTo((await geometry()).chat.width, initial.chat.width); | |
| result.checks.push('Width limits, keyboard nudges, Shift, Home/End, Enter reset and accessible values work'); | |
| await drag(150, false); await divider.press('Escape'); await page.mouse.up(); await frames(); | |
| closeTo((await geometry()).chat.width, initial.chat.width); | |
| assert(!await page.locator('html').evaluate(el => el.classList.contains('is-resizing-columns'))); | |
| await drag(100, false); await divider.dispatchEvent('pointercancel', { pointerId: 1 }); await page.mouse.up(); await frames(); | |
| closeTo((await geometry()).chat.width, initial.chat.width); | |
| await drag(170); const saved = (await geometry()).chat.width; | |
| await page.reload(); await ready(); await frames(); closeTo((await geometry()).chat.width, saved); | |
| await page.setViewportSize({ width: 851, height: 800 }); await frames(); | |
| size = await geometry(); assert(size.chat.width >= 420 && size.main.width - size.chat.width >= 369.9 && !size.overflow); | |
| await page.setViewportSize({ width: 1440, height: 1000 }); await frames(); closeTo((await geometry()).chat.width, saved); | |
| result.checks.push('Cancelled drags roll back; saved ratio survives reload and returns after narrow-window clamping'); | |
| await divider.dblclick(); await frames(); closeTo((await geometry()).chat.width, initial.chat.width); | |
| await page.setViewportSize({ width: 2400, height: 1000 }); await frames(); | |
| size = await geometry(); assert.equal(size.main.width, 1800); assert(size.main.left > 0); | |
| await drag(100); closeTo((await geometry()).chat.width, size.chat.width + 100); | |
| await page.screenshot({ path: '../validation/column-resizer-wide.png', fullPage: true }); | |
| await page.setViewportSize({ width: 1440, height: 1000 }); await frames(); await divider.dblclick(); await frames(); | |
| await page.screenshot({ path: '../validation/column-resizer-desktop.png', fullPage: true }); | |
| await drag(80, false); await page.setViewportSize({ width: 850, height: 800 }); await page.mouse.up(); await frames(); | |
| assert(!await page.locator('html').evaluate(el => el.classList.contains('is-resizing-columns'))); | |
| for (const width of [850,390,320]) { | |
| await page.setViewportSize({ width, height: 844 }); await frames(); | |
| assert(await page.locator('#column-resizer').isHidden()); | |
| size = await geometry(); assert(!size.overflow && size.workspace.top >= size.chat.bottom - 1); | |
| } | |
| await page.screenshot({ path: '../validation/column-resizer-mobile.png', fullPage: true }); | |
| result.checks.push('Double-click resets; centered wide layouts drag accurately; mobile stays stacked and cancels desktop drags'); | |
| const blocked = await browser.newPage({ viewport: { width: 1440, height: 1000 } }); | |
| await blocked.addInitScript(() => { Storage.prototype.getItem = Storage.prototype.setItem = () => { throw new DOMException('Blocked', 'SecurityError'); }; }); | |
| await blocked.goto(url); await blocked.waitForFunction(() => window.browserPi?.terminal); | |
| await blocked.getByRole('separator', { name: 'Resize chat and workspace' }).press('Home'); | |
| closeTo(await blocked.locator('.conversation').evaluate(el => el.getBoundingClientRect().width), 420); | |
| await blocked.close(); result.checks.push('Resizing works with blocked browser storage'); | |
| assert.deepEqual(result.errors, []); result.passed = true; console.log(JSON.stringify(result)); | |
| } catch (error) { | |
| result.failure = error.stack; | |
| await page.screenshot({ path: '../validation/column-resizer-failure.png', fullPage: true }); throw error; | |
| } finally { | |
| await fs.writeFile('../validation/column-resizer.json', JSON.stringify(result, null, 2)); await browser.close(); | |
| } | |