mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-06-16 10:43:18 +03:00
fix(web-test,web-publish): DLB-first approach for combobox fields, fix relative Apache paths
web-test/browser.mjs: fillReferenceField now tries DLB (DropListButton) click before falling back to paste approach. Combobox/enum fields are filled cleanly in one step (click dropdown → select item) instead of the old Shift+F4 → Tab → refocus → paste flow that caused visual artifacts. web-publish v1.1: normalize ApachePath to absolute when agent passes a relative path like "tools/apache24", preventing Apache "Forbidden" errors. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
# web-publish v1.0 — Publish 1C infobase via Apache
|
||||
# web-publish v1.1 — Publish 1C infobase via Apache
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
<#
|
||||
.SYNOPSIS
|
||||
@@ -117,6 +117,10 @@ if (-not $ApachePath) {
|
||||
$projectRoot = (Get-Item $PSScriptRoot).Parent.Parent.Parent.Parent.FullName
|
||||
$ApachePath = Join-Path $projectRoot "tools\apache24"
|
||||
}
|
||||
# Ensure absolute path (agent may pass relative like "tools/apache24")
|
||||
if (-not [System.IO.Path]::IsPathRooted($ApachePath)) {
|
||||
$ApachePath = [System.IO.Path]::GetFullPath((Join-Path (Get-Location).Path $ApachePath))
|
||||
}
|
||||
|
||||
# --- Check / Install Apache ---
|
||||
$httpdExe = Join-Path (Join-Path $ApachePath "bin") "httpd.exe"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# web-publish v1.0 — Publish 1C infobase via Apache
|
||||
# web-publish v1.1 — Publish 1C infobase via Apache
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
|
||||
"""
|
||||
@@ -105,6 +105,9 @@ def main():
|
||||
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
project_root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(script_dir))))
|
||||
apache_path = os.path.join(project_root, 'tools', 'apache24')
|
||||
# Ensure absolute path (agent may pass relative like "tools/apache24")
|
||||
if not os.path.isabs(apache_path):
|
||||
apache_path = os.path.abspath(apache_path)
|
||||
|
||||
port = args.Port
|
||||
|
||||
|
||||
@@ -1259,6 +1259,52 @@ async function fillReferenceField(selector, fieldName, value, formNum) {
|
||||
// 0. Dismiss any leftover error modal from a previous operation
|
||||
await dismissPendingErrors();
|
||||
|
||||
// 0a. Try DLB (DropListButton) first — works cleanly for combobox/enum fields
|
||||
// and also for reference fields that show a dropdown.
|
||||
const inputId = selector.match(/\[id="(.+)"\]/)?.[1];
|
||||
// DLB button ID uses field name without _iN suffix (e.g. form1_Field_DLB, not form1_Field_i0_DLB)
|
||||
const dlbId = inputId.replace(/_i\d+$/, '') + '_DLB';
|
||||
const dlbSelector = `[id="${dlbId}"]`;
|
||||
try {
|
||||
const dlbVisible = await page.evaluate(`document.querySelector('${dlbSelector.replace(/'/g, "\\'")}')?.offsetWidth > 0`);
|
||||
if (dlbVisible) {
|
||||
await page.click(dlbSelector);
|
||||
await page.waitForTimeout(1000);
|
||||
const eddState = await page.evaluate(`(() => {
|
||||
const edd = document.getElementById('editDropDown');
|
||||
if (!edd || edd.offsetWidth === 0) return { visible: false };
|
||||
const eddTexts = [...edd.querySelectorAll('.eddText')].filter(el => el.offsetWidth > 0);
|
||||
return {
|
||||
visible: true,
|
||||
items: eddTexts.map(el => {
|
||||
const r = el.getBoundingClientRect();
|
||||
return { name: el.innerText?.trim() || '', x: r.x + r.width / 2, y: r.y + r.height / 2 };
|
||||
})
|
||||
};
|
||||
})()`);
|
||||
if (eddState.visible && eddState.items?.length > 0) {
|
||||
const target = normYo(text.toLowerCase());
|
||||
const candidates = eddState.items.filter(i => !i.name.startsWith('Создать'));
|
||||
let match = candidates.find(i => normYo(i.name.replace(/\s*\([^)]*\)\s*$/, '').toLowerCase()) === target);
|
||||
if (!match) match = candidates.find(i => normYo(i.name.toLowerCase()).includes(target));
|
||||
if (!match) match = candidates.find(i => {
|
||||
const name = normYo(i.name.replace(/\s*\([^)]*\)\s*$/, '').toLowerCase());
|
||||
return name.includes(target) || target.includes(name);
|
||||
});
|
||||
if (match) {
|
||||
await page.mouse.click(match.x, match.y);
|
||||
await waitForStable();
|
||||
await dismissPendingErrors();
|
||||
return { field: fieldName, ok: true, method: 'dropdown',
|
||||
value: match.name.replace(/\s*\([^)]*\)\s*$/, '') };
|
||||
}
|
||||
// No match in DLB dropdown — close and fall through to paste approach
|
||||
await page.keyboard.press('Escape');
|
||||
await page.waitForTimeout(300);
|
||||
}
|
||||
}
|
||||
} catch { /* DLB approach failed — fall through to paste */ }
|
||||
|
||||
// 1. Focus (handle surface/modal overlay from previous interaction)
|
||||
try {
|
||||
await page.click(selector);
|
||||
@@ -1279,6 +1325,7 @@ async function fillReferenceField(selector, fieldName, value, formNum) {
|
||||
}
|
||||
|
||||
// 2. If field already has a value, clear using Shift+F4 (native 1C mechanism).
|
||||
// This is needed for reference fields — Shift+F4 properly clears the ref link.
|
||||
const currentVal = await page.evaluate(`document.querySelector('${escapedSel}')?.value || ''`);
|
||||
if (currentVal) {
|
||||
await page.keyboard.press('Shift+F4');
|
||||
|
||||
Reference in New Issue
Block a user