Spaces:
Running
Running
Download tests/browser/fullstack.spec.js from ThomasHeisig/MHRN-Space: direct link, hf CLI and curl.
- Browser
- Download file 13 kB
-
https://huggingface.co/spaces/ThomasHeisig/MHRN-Space/resolve/main/tests/browser/fullstack.spec.js
- Command line
-
hf download hf://spaces/ThomasHeisig/MHRN-Space/tests/browser/fullstack.spec.js
-
curl -L -o fullstack.spec.js https://huggingface.co/spaces/ThomasHeisig/MHRN-Space/resolve/main/tests/browser/fullstack.spec.js
13 kB
| import { test, expect } from '@playwright/test'; | |
| import { selectRoute, selectLabStage, selectResearchView } from './routes.js'; | |
| test.use({ baseURL: 'http://127.0.0.1:4174' }); | |
| for (const port of [4174, 4175]) { | |
| test(`real server ${port}: routing, catalog, MSBA and shared file/chat renderer`, async ({ page }) => { | |
| const errors = []; | |
| page.on('pageerror', error => errors.push(error.message)); | |
| await page.goto(`http://127.0.0.1:${port}/`); | |
| await selectLabStage(page, 'question'); | |
| await expect(page.locator('#workflow-research-results')).toBeVisible(); | |
| await page.locator('#workflow-research-search').fill('RQ-MSBA-E01'); | |
| await expect(page.locator('.research-rq-card')).toHaveCount(1); | |
| await page.locator('.research-rq-card').click(); | |
| await expect(page.locator('#workflow-research-results')).toContainText('OPERATIONAL'); | |
| await page.locator('#workflow-research-detail-close').click(); | |
| await expect(page.locator('#workflow-research-detail')).toBeHidden(); | |
| await page.locator('#workflow-research-operational').check(); | |
| await expect(page.locator('.research-rq-card')).toHaveCount(1); | |
| await page.locator('#workflow-research-operational').uncheck(); | |
| await selectRoute(page, 'old', 'wesen-symbiosis'); | |
| await expect(page.locator('#wesen-neural-symbiosis')).toBeVisible(); | |
| await expect(page.locator('#wesen-msba-pathways')).toContainText('Audio'); | |
| await selectRoute(page, 'old', 'wesen-profile'); | |
| await expect(page.locator('#wesen-profile-identity')).toBeVisible(); | |
| await expect(page.locator('#wesen-profile-identity')).toContainText('Profile & Identität'); | |
| await selectLabStage(page, 'question'); | |
| await selectResearchView(page, 'files'); | |
| await page.locator('#fm-popup-toggle').uncheck(); | |
| await page.locator('.fm-source-btn[data-source="docs"]').click(); | |
| const preview = page.locator('.fm-tree-file').filter({ has: page.locator('.fm-file-label', { hasText: 'preview.md' }) }); | |
| const csv = page.locator('.fm-tree-file').filter({ has: page.locator('.fm-file-label', { hasText: 'data.csv' }) }); | |
| await expect(preview).toBeVisible(); | |
| await expect(csv).toBeVisible(); | |
| await page.locator('.fm-filter-chip').filter({ hasText: /^Markdown$/ }).click(); | |
| await expect(preview).toBeVisible(); | |
| await expect(csv).toBeHidden(); | |
| await page.locator('.fm-filter-chip').filter({ hasText: /^All$/ }).click(); | |
| await expect(csv).toBeVisible(); | |
| await preview.locator('.fm-file-label').click(); | |
| const viewer = page.locator('#fm-viewer'); | |
| await expect(viewer).toHaveAttribute('data-render-state', 'ready'); | |
| await expect(viewer.locator('.file-renderer-body h2')).toHaveText('Gemeinsamer Renderer'); | |
| await expect(viewer.locator('.file-renderer-body script')).toHaveCount(0); | |
| expect(await page.evaluate(() => window.unsafeExecuted)).toBeUndefined(); | |
| await viewer.getByRole('button', { name: 'Im Chat anzeigen', exact: true }).click(); | |
| const card = page.locator('#research-chat-log .chat-file-card .file-renderer'); | |
| await expect(card).toHaveAttribute('data-render-state', 'ready'); | |
| await expect(card.locator('.file-renderer-body')).toContainText(/Dateiinhalt|File content/); | |
| await expect(card.getByRole('button', { name: 'Bearbeiten', exact: true })).toHaveCount(0); | |
| await card.getByRole('button', { name: 'Messdaten', exact: true }).click(); | |
| await expect(page.locator('[data-file-key="docs/sample.json"] .file-renderer')).toHaveAttribute('data-file-kind', 'json'); | |
| await page.screenshot({ path: `test-results/fullstack-${port}.png`, fullPage: true }); | |
| expect(errors).toEqual([]); | |
| }); | |
| } | |
| test('real file service: edits persist, stale writers fail, originals stream', async ({ page }) => { | |
| await page.goto('http://127.0.0.1:4174/'); | |
| const reference = 'notes/browser-edit.md'; | |
| const url = `/api/files/document/${encodeURIComponent(reference)}?source=docs`; | |
| const created = await page.request.put(url, { data: { action: 'create', content: '# Original\n' } }); | |
| expect(created.ok()).toBeTruthy(); | |
| const data = await created.json(); | |
| const edited = await page.request.put(url, { data: { action: 'write', content: '# Updated\n', expected_sha256: data.file.sha256 } }); | |
| expect(edited.ok()).toBeTruthy(); | |
| const stale = await page.request.put(url, { data: { action: 'write', content: 'stale', expected_sha256: data.file.sha256 } }); | |
| expect(stale.status()).toBe(409); | |
| const raw = await page.request.get(`/api/files/raw/${encodeURIComponent(reference)}?source=docs`, { headers: { Range: 'bytes=0-8' } }); | |
| expect(raw.status()).toBe(206); | |
| expect(await raw.text()).toBe('# Updated'); | |
| const protectedWrite = await page.request.put('/api/files/document/registry%2Fquestions.yaml?source=research', { data: { action: 'write', content: '[]', expected_sha256: 'invalid' } }); | |
| expect(protectedWrite.status()).toBe(403); | |
| const unknown = await page.request.get('/api/files/preview/unknown.b5d?source=docs'); | |
| expect((await unknown.json()).kind).toBe('binary'); | |
| }); | |
| test('real registered batch: runner, manifest, DATA, report and central rendering', async ({ page }) => { | |
| await page.goto('http://127.0.0.1:4174/'); | |
| const id = `EXP-BROWSER-${Date.now()}`; | |
| const response = await page.request.post('/api/experiment/workflow/batch', { data: { | |
| batch_id: id, protocols: ['temporal_order_spiking_v1'], | |
| protocol_options: { temporal_order_spiking_v1: { seeds: '101-120', ticks: 32 } }, | |
| }, timeout: 30_000 }); | |
| expect(response.ok()).toBeTruthy(); | |
| const result = await response.json(); | |
| expect(result.failed, JSON.stringify(result)).toBe(0); | |
| expect(result.completed).toBe(1); | |
| const path = `experiments/${id}-01/manifest.json`; | |
| const manifestResponse = await page.request.get(`/api/files/preview/${encodeURIComponent(path)}?source=research`); | |
| expect(manifestResponse.ok()).toBeTruthy(); | |
| const descriptor = await manifestResponse.json(); | |
| const manifest = JSON.parse(descriptor.content); | |
| expect(manifest.experiment_status).toBe('completed'); | |
| expect(manifest.epistemic_layers.evid).toContain('not_created'); | |
| expect(descriptor.read_only).toBe(true); | |
| await selectLabStage(page, 'question'); | |
| await page.evaluate(async (filePath) => { | |
| const module = await import('/file-renderer.js'); | |
| const host = document.createElement('section'); host.id = 'fullstack-artifact'; document.querySelector('#tab-research').prepend(host); | |
| await module.renderFile(host, { source: 'research', path: filePath }); | |
| }, path); | |
| await expect(page.locator('#fullstack-artifact')).toHaveAttribute('data-render-state', 'ready'); | |
| await expect(page.locator('#fullstack-artifact')).toContainText('temporal_order_spiking_v1'); | |
| }); | |
| test('real inventory changes reach the Wesen pipeline view without authorizing devices', async ({ page }) => { | |
| await page.goto('http://127.0.0.1:4174/'); | |
| await selectRoute(page, 'old', 'wesen-symbiosis'); | |
| await page.request.post('/__test__/inventory', { data: { available: true } }); | |
| const camera = page.locator('#wesen-symbiosis-pipelines .wesen-symbiosis-item').filter({ hasText: 'Camera' }); | |
| const robot = page.locator('#wesen-symbiosis-pipelines .wesen-symbiosis-item').filter({ hasText: 'Robotics' }); | |
| await expect(camera).toHaveClass(/reachable/); | |
| await expect(camera).toContainText('endpoint reachable'); | |
| await expect(robot).toContainText('endpoint reachable'); | |
| await expect.poll(async () => { | |
| const response = await page.request.get('/api/embodiment/connections'); | |
| const data = await response.json(); | |
| return data.connections.find(item => item.connection_id === 'sensor.camera.browser')?.available; | |
| }).toBe(true); | |
| await page.request.post('/__test__/inventory', { data: { available: false } }); | |
| await expect.poll(async () => { | |
| const response = await page.request.get('/api/embodiment/connections'); | |
| const data = await response.json(); | |
| const item = data.connections.find(item => item.connection_id === 'sensor.camera.browser'); | |
| return item && !item.available && !item.authorized && !item.active; | |
| }).toBe(true); | |
| await expect(camera).toContainText('endpoint unavailable'); | |
| await expect(robot).toContainText('endpoint unavailable'); | |
| await expect(page.locator('#wesen-neural-symbiosis')).toContainText('EXPERIMENT CONTROL'); | |
| await expect(page.locator('#wesen-neural-symbiosis')).toContainText('Productive Gateway: LOCKED'); | |
| }); | |
| test('canonical file viewer: split editor live preview and stale-write conflict diff', async ({ page }) => { | |
| await page.goto('http://127.0.0.1:4174/'); | |
| const reference = `notes/split-editor-${Date.now()}.md`; | |
| const url = `/api/files/document/${encodeURIComponent(reference)}?source=docs`; | |
| const created = await page.request.put(url, { data: { action: 'create', content: '# Initial\n\nBody\n' } }); | |
| expect(created.ok()).toBeTruthy(); | |
| const createdData = await created.json(); | |
| await selectRoute(page, 'files', 'browse'); | |
| await page.locator('#fm-popup-toggle').uncheck(); | |
| // Exercise the actual shared viewer and its layout, not an orphan body child | |
| // placed underneath fixed chrome by the test itself. | |
| await page.evaluate(filePath => window.openBrain5DFile('docs', filePath), reference); | |
| const host = page.locator('#fm-viewer'); | |
| await expect(host).toHaveAttribute('data-render-state', 'ready'); | |
| await host.getByRole('button', { name: 'Bearbeiten', exact: true }).click(); | |
| await expect(host.locator('.file-renderer-editor-split')).toBeVisible(); | |
| const editor = host.locator('.file-renderer-editor'); | |
| await editor.fill('# Live Preview\n\nUpdated in browser'); | |
| await expect(host.locator('.file-renderer-editor-preview')).toContainText('Live Preview'); | |
| await expect(host.locator('.file-renderer-editor-preview')).toContainText('Updated in browser'); | |
| const remote = await page.request.put(url, { | |
| data: { action: 'write', content: '# Remote Version\n', expected_sha256: createdData.file.sha256 }, | |
| }); | |
| expect(remote.ok()).toBeTruthy(); | |
| await host.getByRole('button', { name: 'Speichern', exact: true }).click(); | |
| await expect(host.locator('.file-renderer-body')).toContainText('Speicherkonflikt'); | |
| await expect(host.locator('.file-renderer-body')).toContainText('Remote Version'); | |
| await expect(host.locator('.file-renderer-body')).toContainText('Live Preview'); | |
| }); | |
| test('central research review inbox exposes human review actions', async ({ page }) => { | |
| await page.goto('http://127.0.0.1:4174/'); | |
| await selectRoute(page, 'review', 'inbox'); | |
| await expect(page.locator('#review-inbox-list')).toBeVisible(); | |
| const inboxResponse = await page.request.get('/api/research/reviews'); | |
| expect(inboxResponse.ok()).toBeTruthy(); | |
| const inbox = await inboxResponse.json(); | |
| expect(Array.isArray(inbox.items)).toBeTruthy(); | |
| await expect(page.locator('#review-open-count')).toHaveText(String(inbox.open ?? 0)); | |
| if (inbox.items.length) { | |
| await expect(page.locator('#review-inbox-list [data-review-reviewer]').first()).toBeVisible(); | |
| await expect(page.locator('#review-inbox-list [data-review-comments]').first()).toBeVisible(); | |
| await expect(page.locator('#review-inbox-list [data-review-decision="accepted_as_interpretation"]').first()).toBeVisible(); | |
| await expect(page.locator('#review-inbox-list [data-review-decision="rejected"]').first()).toBeVisible(); | |
| } | |
| }); | |
| test('external review: subtab, public readiness and central viewer without private responses', async ({ page }) => { | |
| await page.goto('http://127.0.0.1:4174/'); | |
| await selectLabStage(page, 'question'); | |
| await selectResearchView(page, 'external'); | |
| const panel = page.locator('#external-review-status'); | |
| await expect(panel).toBeVisible(); | |
| await expect(panel).toContainText(/135 (Questions|Fragen)/); | |
| await expect(panel).toContainText('Beurteilung ausstehend'); | |
| const metadata = await (await page.request.get('/api/research/external-review')).json(); | |
| expect(metadata.response_count).toBeNull(); | |
| expect(metadata.scientific_evidence).toBe(false); | |
| await panel.locator('#external-review-method').click(); | |
| await expect(page.locator('#fm-viewer-dialog')).toBeVisible(); | |
| await expect(page.locator('#fm-dialog-viewer')).toHaveAttribute('data-render-state', 'ready'); | |
| await expect(page.locator('#fm-dialog-viewer')).toContainText('Abschlusskriterien'); | |
| }); | |
| test('external review: stale success is cleared after failed status fetch', async ({ page }) => { | |
| await page.goto('http://127.0.0.1:4174/'); | |
| await selectLabStage(page, 'question'); | |
| await selectResearchView(page, 'external'); | |
| await expect(page.locator('#external-review-summary')).toContainText(/135 (Questions|Fragen)/); | |
| await page.route('**/api/research/external-review', route => route.fulfill({ status: 503, body: '{}' })); | |
| await page.locator('#external-review-refresh').click(); | |
| await expect(page.locator('#external-review-summary')).toContainText('Nicht verf\u00fcgbar'); | |
| await expect(page.locator('#external-review-stages dt')).toHaveCount(0); | |
| }); | |