mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-09-15 22:35:23 +03:00
feat(web-test): add navigateLink() for direct 1C navigation links
- navigateLink(url): opens form via Shift+F11 dialog with clipboard paste - Grant clipboard-read/write permissions on browser context creation - Register navigateLink in ACTION_FNS for auto-error detection - Document in SKILL.md with examples (e1cib/list/...) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
0fbdd298ca
commit
e58f5c1f82
@@ -98,6 +98,7 @@ In `exec` sandbox, all browser.mjs functions are available as globals — no `im
|
|||||||
|----------|-------------|
|
|----------|-------------|
|
||||||
| `navigateSection(name)` | Go to section (fuzzy match). Returns `{ sections, commands }` |
|
| `navigateSection(name)` | Go to section (fuzzy match). Returns `{ sections, commands }` |
|
||||||
| `openCommand(name)` | Open command from function panel (fuzzy). Returns form state |
|
| `openCommand(name)` | Open command from function panel (fuzzy). Returns form state |
|
||||||
|
| `navigateLink(url)` | Open 1C navigation link via Shift+F11 dialog. Returns form state |
|
||||||
| `switchTab(name)` | Switch to open tab/window (fuzzy). Returns form state |
|
| `switchTab(name)` | Switch to open tab/window (fuzzy). Returns form state |
|
||||||
|
|
||||||
### Reading
|
### Reading
|
||||||
@@ -214,6 +215,17 @@ Hint: if `readTable()` returns `hierarchical: true`, the list has groups.
|
|||||||
| `F4` | Reference field focused | Open selection form |
|
| `F4` | Reference field focused | Open selection form |
|
||||||
| `Alt+F` | List/table form | Open advanced search dialog |
|
| `Alt+F` | List/table form | Open advanced search dialog |
|
||||||
|
|
||||||
|
### Navigation links
|
||||||
|
|
||||||
|
```js
|
||||||
|
// Open any form directly by 1C navigation link (e1cib/...)
|
||||||
|
await navigateLink('e1cib/list/РегистрНакопления.ЗаказыКлиентов');
|
||||||
|
await navigateLink('e1cib/list/Документ.ЗаказКлиента');
|
||||||
|
await navigateLink('e1cib/list/Справочник.Контрагенты');
|
||||||
|
```
|
||||||
|
|
||||||
|
Bypasses section/command navigation. Useful for registers, journals, and any form with a known path.
|
||||||
|
|
||||||
### Submenu navigation
|
### Submenu navigation
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
|||||||
@@ -40,7 +40,10 @@ export async function connect(url) {
|
|||||||
await page.goto(url, { waitUntil: 'domcontentloaded', timeout: LOAD_TIMEOUT });
|
await page.goto(url, { waitUntil: 'domcontentloaded', timeout: LOAD_TIMEOUT });
|
||||||
} else {
|
} else {
|
||||||
browser = await chromium.launch({ headless: false, args: ['--start-maximized'] });
|
browser = await chromium.launch({ headless: false, args: ['--start-maximized'] });
|
||||||
const context = await browser.newContext({ viewport: null });
|
const context = await browser.newContext({
|
||||||
|
viewport: null,
|
||||||
|
permissions: ['clipboard-read', 'clipboard-write'],
|
||||||
|
});
|
||||||
page = await context.newPage();
|
page = await context.newPage();
|
||||||
|
|
||||||
// Capture seanceId from network requests for graceful logout
|
// Capture seanceId from network requests for graceful logout
|
||||||
@@ -337,6 +340,34 @@ export async function switchTab(name) {
|
|||||||
return await getFormState();
|
return await getFormState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Navigate to a 1C navigation link via Shift+F11 dialog. Returns new form state. */
|
||||||
|
export async function navigateLink(url) {
|
||||||
|
ensureConnected();
|
||||||
|
await dismissPendingErrors();
|
||||||
|
const formBefore = await page.evaluate(detectFormScript());
|
||||||
|
|
||||||
|
// Copy link to clipboard, press Shift+F11 (opens "Go to link" dialog with clipboard content)
|
||||||
|
await page.evaluate(`navigator.clipboard.writeText(${JSON.stringify(url)})`);
|
||||||
|
await page.keyboard.press('Shift+F11');
|
||||||
|
await waitForStable();
|
||||||
|
|
||||||
|
// Click "Перейти" in the navigation dialog
|
||||||
|
const dialog = await page.evaluate(detectFormScript());
|
||||||
|
if (dialog != null && dialog !== formBefore) {
|
||||||
|
const btns = await page.$$(`#form${dialog}_container a.press`);
|
||||||
|
for (const b of btns) {
|
||||||
|
const txt = (await b.textContent())?.trim();
|
||||||
|
if (txt === 'Перейти') { await b.click(); break; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await waitForStable(formBefore);
|
||||||
|
const state = await getFormState();
|
||||||
|
const err = await checkForErrors();
|
||||||
|
if (err) state.errors = err;
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
/** Read current form state. Single evaluate call via combined script. */
|
/** Read current form state. Single evaluate call via combined script. */
|
||||||
export async function getFormState() {
|
export async function getFormState() {
|
||||||
ensureConnected();
|
ensureConnected();
|
||||||
|
|||||||
@@ -117,8 +117,8 @@ async function executeScript(code) {
|
|||||||
// and stop execution immediately with diagnostic info
|
// and stop execution immediately with diagnostic info
|
||||||
const ACTION_FNS = [
|
const ACTION_FNS = [
|
||||||
'clickElement', 'fillFields', 'selectValue', 'fillTableRow',
|
'clickElement', 'fillFields', 'selectValue', 'fillTableRow',
|
||||||
'deleteTableRow', 'openCommand', 'navigateSection', 'closeForm',
|
'deleteTableRow', 'openCommand', 'navigateSection', 'navigateLink',
|
||||||
'filterList', 'unfilterList'
|
'closeForm', 'filterList', 'unfilterList'
|
||||||
];
|
];
|
||||||
for (const name of ACTION_FNS) {
|
for (const name of ACTION_FNS) {
|
||||||
if (typeof exports[name] !== 'function') continue;
|
if (typeof exports[name] !== 'function') continue;
|
||||||
|
|||||||
Reference in New Issue
Block a user