import { TestRunner } from './src/tools/autotest/test-runner.js'; function assert(condition, message) { if (!condition) throw new Error(message); } class FakeLocator { constructor(key, counts) { this.key = key; this.counts = counts; } first() { return this; } locator(childSelector) { return new FakeLocator(`${this.key} ${childSelector}`, this.counts); } filter({ hasText }) { return new FakeLocator(`${this.key}|text=${hasText}`, this.counts); } async count() { return this.counts[this.key] || 0; } async waitFor() { if (await this.count()) return; throw new Error('not attached'); } } console.log('\n── AutoTest vlid Resolution ──'); const runner = new TestRunner({ baseUrl: 'https://example.test/app' }); runner.page = { locator(selector) { return new FakeLocator(selector, { '[data-vl-id="submitForm"] button': 1, '[data-vl-id="submitForm"]': 1, '[data-vl-id="navItem"]|text=课程管理': 1, }); }, getByRole() { return new FakeLocator('__missing__', {}); }, getByText() { return new FakeLocator('__missing__', {}); }, getByPlaceholder() { return new FakeLocator('__missing__', {}); }, getByLabel() { return new FakeLocator('__missing__', {}); }, }; const submitLocator = await runner._resolveSelector('vlid:submitForm'); assert(submitLocator.key === '[data-vl-id="submitForm"] button', 'vlid button should resolve to the clickable button child before the wrapper'); const navLocator = await runner._resolveSelector('vlid:navItem[text="课程管理"]'); assert(navLocator.key === '[data-vl-id="navItem"]|text=课程管理', 'hybrid vlid selector should preserve text disambiguation for repeated ids'); const strictRunner = new TestRunner({ baseUrl: 'https://example.test/app' }); strictRunner.page = { locator(selector) { return new FakeLocator(selector, { 'input:visible, textarea:visible': 1, }); }, getByRole() { return new FakeLocator('__missing__', {}); }, getByText() { return new FakeLocator('__missing__', {}); }, getByPlaceholder() { return new FakeLocator('__missing__', {}); }, getByLabel() { return new FakeLocator('__missing__', {}); }, }; const strictInputLocator = await strictRunner._resolveSelector('vlid:formDescInput input'); assert( strictInputLocator.key === '[data-vl-id="formDescInput"] input, [data-vl-id="formDescInput"] textarea, [data-vl-id="formDescInput"] [contenteditable="true"]', 'missing vlid input should stay strict on data-vl-id instead of degrading to a generic visible input' ); const directInputRunner = new TestRunner({ baseUrl: 'https://example.test/app' }); directInputRunner.page = { locator(selector) { return new FakeLocator(selector, { '[data-vl-id="formTitleInput"]': 1, }); }, getByRole() { return new FakeLocator('__missing__', {}); }, getByText() { return new FakeLocator('__missing__', {}); }, getByPlaceholder() { return new FakeLocator('__missing__', {}); }, getByLabel() { return new FakeLocator('__missing__', {}); }, }; const directInputLocator = await directInputRunner._resolveSelector('vlid:formTitleInput input'); assert( directInputLocator.key === '[data-vl-id="formTitleInput"]', 'vlid input selector should fall back to the base element when the data-vl-id is attached directly to the fillable element' ); console.log('PASS test-autotest-vlid-resolution.js');