101 lines
4.7 KiB
JavaScript
101 lines
4.7 KiB
JavaScript
// Запуск через browser_ide.sh: настоящий notebook editor, локальное ядро и webview.
|
|
const assert = require('node:assert/strict');
|
|
const fs = require('node:fs');
|
|
const path = require('node:path');
|
|
const { chromium } = require('playwright');
|
|
|
|
const notebookName = 'lakehouse-browser-smoke.ipynb';
|
|
const notebook = JSON.parse(fs.readFileSync(
|
|
path.join(__dirname, '../notebooks/01_environment_and_smoke_test.ipynb'), 'utf8',
|
|
));
|
|
const smokeCell = notebook.cells.findIndex(cell =>
|
|
cell.source.join('').includes('smoke_report = run_cluster_smoke(spark)'),
|
|
);
|
|
|
|
async function openNotebook(page) {
|
|
await page.keyboard.press('Control+p');
|
|
await page.keyboard.type(`/tmp/${notebookName}`);
|
|
await page.getByRole('option').filter({ hasText: notebookName }).first().waitFor();
|
|
await page.keyboard.press('Enter');
|
|
await page.getByRole('list', { name: /Notebook Use/ }).waitFor();
|
|
}
|
|
|
|
async function checkOutput(page) {
|
|
// Notebook editor виртуализирует ячейки: сначала показываем нужную ячейку.
|
|
const list = page.getByRole('list', { name: /Notebook Use/ });
|
|
await list.press('Control+Home');
|
|
for (let i = 0; i < smokeCell; i++) await list.press('ArrowDown');
|
|
await page.getByRole('button', {
|
|
name: `Cell ${smokeCell + 1} of ${notebook.cells.length}`, exact: true,
|
|
}).waitFor();
|
|
|
|
for (let attempt = 0; attempt < 30; attempt++) {
|
|
for (const frame of page.frames()) {
|
|
const output = frame.getByText('result_sum=499999500000', { exact: false });
|
|
if (await output.count() && await output.first().isVisible()) return;
|
|
}
|
|
await page.waitForTimeout(500);
|
|
}
|
|
throw new Error('Notebook webview did not render the expected Spark result');
|
|
}
|
|
|
|
(async () => {
|
|
assert(smokeCell >= 0, 'Module 1 must contain the cluster smoke cell');
|
|
const browser = await chromium.launch({ headless: true });
|
|
const page = await browser.newPage({ viewport: { width: 1440, height: 1000 } });
|
|
page.setDefaultTimeout(30000);
|
|
const webviewErrors = [];
|
|
page.on('console', message => {
|
|
if (/Error loading webview|Could not register.*service.?worker/i.test(message.text())) {
|
|
webviewErrors.push(message.text());
|
|
}
|
|
});
|
|
try {
|
|
await page.goto(process.env.IDE_URL || 'http://localhost:8889', {
|
|
waitUntil: 'domcontentloaded',
|
|
});
|
|
assert(await page.evaluate(() => isSecureContext && 'serviceWorker' in navigator));
|
|
await page.getByRole('tree', { name: 'Files Explorer' }).waitFor();
|
|
// Баннер появляется позже Explorer; при повторном тесте доверие уже сохранено.
|
|
const restricted = page.getByRole('banner').filter({ hasText: 'Restricted Mode' });
|
|
await restricted.waitFor({ timeout: 10000 }).catch(error => {
|
|
if (error.name !== 'TimeoutError') throw error;
|
|
});
|
|
if (await restricted.count()) {
|
|
await restricted.getByRole('button', { name: 'Manage', exact: true }).click();
|
|
await page.getByRole('button', { name: 'Trust', exact: true }).click();
|
|
await page.getByRole('button', { name: 'Close Modal Editor (Escape)' }).click();
|
|
await restricted.waitFor({ state: 'hidden' });
|
|
}
|
|
console.log('PASS: workspace trust enabled');
|
|
|
|
await openNotebook(page);
|
|
await page.getByRole('button', { name: 'Select Kernel', exact: true }).click();
|
|
await page.getByRole('option', { name: 'Python Environments...' }).click();
|
|
await page.getByRole('option').filter({ hasText: '/usr/bin/python3' }).click();
|
|
console.log('PASS: notebook editor and local Python kernel selection');
|
|
|
|
await page.getByRole('button', { name: 'Run All', exact: true }).click();
|
|
await page.getByRole('button', { name: 'Interrupt', exact: true }).waitFor();
|
|
await page.getByRole('button', { name: 'Run All', exact: true }).waitFor({ timeout: 120000 });
|
|
await checkOutput(page);
|
|
await page.keyboard.press('Control+s');
|
|
console.log('PASS: Spark output rendered in notebook webview over HTTP localhost');
|
|
|
|
await page.getByRole('tab', { name: notebookName, exact: true })
|
|
.getByRole('button', { name: 'Close (Ctrl+W)' }).click();
|
|
await openNotebook(page);
|
|
await checkOutput(page);
|
|
assert.deepEqual(webviewErrors, []);
|
|
await page.screenshot({ path: '/artifacts/notebook.png' });
|
|
await page.getByRole('tab', { name: notebookName, exact: true })
|
|
.getByRole('button', { name: 'Close (Ctrl+W)' }).click();
|
|
console.log('PASS: saved notebook reopened with its output');
|
|
} catch (error) {
|
|
await page.screenshot({ path: '/artifacts/failure.png' }).catch(() => {});
|
|
throw error;
|
|
} finally {
|
|
await browser.close();
|
|
}
|
|
})().catch(error => { console.error(error); process.exitCode = 1; });
|