feat(web-test): M6-MVP follow-up — 13-misc setup + URL webtest-runner

13-misc.test.mjs: setup-шаг упрощён до `assert.ok(existsSync(epfPath))`.
EPF-сборку (epf-init → form-add → form-compile → epf-build) забрал
_hooks.mjs.prepare() — здесь только проверка артефакта с понятной
ошибкой при отсутствии: «запустите раннер с `-- --rebuild-epf`».

webtest.config.mjs: URL обоих контекстов переключён на
`/webtest-runner/ru_RU` — отдельная публикация автономного стенда,
не конфликтует с интерактивной разведкой через `/webtest` на 8081.
This commit is contained in:
Nick Shirokov
2026-05-12 20:25:54 +03:00
parent 5c734202b6
commit 96dad75b2f
2 changed files with 12 additions and 48 deletions
+6 -46
View File
@@ -5,57 +5,17 @@ export const timeout = 120000;
export default async function({ openFile, closeForm, getFormState, assert, step, log }) {
const fs = await import('fs');
const path = await import('path');
const cp = await import('child_process');
const dir = 'test-tmp/13-openfile';
const srcDir = path.join(dir, 'src');
const srcXml = path.join(srcDir, 'ТестОткрытия.xml');
const buildDir = path.join(dir, 'build');
const epfPath = path.join(buildDir, 'ТестОткрытия.epf');
await step('setup: собрать тестовый EPF через epf-init + form-add + form-compile + epf-build (идемпотентно)', async () => {
if (fs.existsSync(epfPath)) {
log(`EPF уже собран: ${epfPath}, размер=${fs.statSync(epfPath).size}`);
return;
}
const run = (script, args) => {
const r = cp.spawnSync('powershell.exe', ['-NoProfile', '-File', script, ...args], { encoding: 'utf-8' });
return { code: r.status, stdout: r.stdout, stderr: r.stderr };
};
// 1. epf-init — XML scaffold
if (!fs.existsSync(srcXml)) {
const init = run('.claude/skills/epf-init/scripts/init.ps1',
['-Name', 'ТестОткрытия', '-Synonym', 'Тест открытия из файла', '-SrcDir', srcDir]);
assert.equal(init.code, 0, `epf-init exit=0 (stderr: ${init.stderr?.slice(0, 200)})`);
}
// 2. form-add — пустая форма
const formDir = path.join(srcDir, 'ТестОткрытия/Forms/Форма');
if (!fs.existsSync(path.join(formDir, 'Ext/Form.xml'))) {
const fa = run('.claude/skills/form-add/scripts/form-add.ps1',
['-ObjectPath', srcXml, '-FormName', 'Форма']);
assert.equal(fa.code, 0, 'form-add успешен');
}
// 3. form-compile — добавить текстовую декорацию
const formJsonPath = path.join(dir, 'form.json');
fs.writeFileSync(formJsonPath, JSON.stringify({
title: 'Тест открытия',
elements: [
{ label: 'Заголовок', title: 'Это тестовая обработка для проверки openFile' }
]
}, null, 2), 'utf-8');
const fc = run('.claude/skills/form-compile/scripts/form-compile.ps1',
['-JsonPath', formJsonPath, '-OutputPath', path.join(formDir, 'Ext/Form.xml')]);
assert.equal(fc.code, 0, `form-compile успешен (stderr: ${fc.stderr?.slice(0, 200)})`);
// 4. epf-build — собрать EPF
const build = run('.claude/skills/epf-build/scripts/epf-build.ps1',
['-SourceFile', srcXml, '-OutputFile', epfPath,
'-V8Path', 'C:\\Program Files\\1cv8\\8.3.24.1691\\bin']);
log(`epf-build exit=${build.code}`);
assert.equal(build.code, 0, `epf-build успешен (stderr: ${build.stderr?.slice(0, 200)})`);
assert.ok(fs.existsSync(epfPath), 'EPF создан на диске');
log(`EPF: ${epfPath} size=${fs.statSync(epfPath).size}`);
await step('setup: тестовый EPF должен быть собран в prepare()', async () => {
// Сборка переехала в tests/web-test/_hooks.mjs (EPF_SPEC + buildEpf).
// Если EPF отсутствует — запустить с `-- --rebuild-epf` или `-- --rebuild-stand`.
assert.ok(fs.existsSync(epfPath),
`EPF не найден: ${epfPath}. Запустите раннер с '-- --rebuild-epf' для сборки.`);
log(`EPF готов: ${epfPath} size=${fs.statSync(epfPath).size}`);
});
await step('openFile: открывает EPF с формой и текстовой декорацией (security confirm — авто)', async () => {
+6 -2
View File
@@ -1,10 +1,14 @@
// Default config for tests/web-test. CLI URL still overrides defaultContext URL.
// Two contexts pointing at the same webtest publication — represent two independent
// 1C sessions (different cookies), used by multi-context tests to simulate two users.
//
// AppName `webtest-runner` отличается от интерактивной публикации `webtest` на :8081 —
// автономный стенд (см. tests/web-test/_hooks.mjs) использует свой URL, чтобы не
// конфликтовать с ручной разведкой и работать поверх отдельного Apache на :9191.
export default {
contexts: {
a: { url: 'http://localhost:9191/webtest/ru_RU' },
b: { url: 'http://localhost:9191/webtest/ru_RU' },
a: { url: 'http://localhost:9191/webtest-runner/ru_RU' },
b: { url: 'http://localhost:9191/webtest-runner/ru_RU' },
},
defaultContext: 'a',
// isolation: 'tab' (default) — persistent context, tabs in one window, 1С extension loads.