import assert from "node:assert/strict"; import { test } from "node:test"; import { generateLocators } from "../src/locator.js"; import type { RawActionableElement } from "../src/types.js"; function raw(overrides: Partial): RawActionableElement { return { uid: "button_0_Open settings", tag: "button", role: "button", accessibleName: "Open settings", text: "Open settings", label: null, placeholder: null, attributes: { "data-testid": "open-settings", id: "openSettings" }, bbox: { x: 0, y: 0, width: 100, height: 30 }, visibility: { visible: true, enabled: true, editable: false, receivesEvents: true }, ...overrides, }; } test("locator generation prioritizes user-facing Playwright locators before CSS fallbacks", () => { const candidates = generateLocators("el_test", raw({})); assert.equal(candidates[0].strategy, "role"); assert.equal(candidates[0].framework, "playwright"); assert.equal(candidates.some((candidate) => candidate.strategy === "testId"), true); assert.equal(candidates.at(-1)?.strategy, "css"); }); test("locator generation keeps CSS as fallback for id and name", () => { const candidates = generateLocators( "el_input", raw({ tag: "input", role: "textbox", accessibleName: "Query", text: null, label: "Query", placeholder: "Search customers", attributes: { id: "queryInput", name: "q" }, }), ); assert.equal(candidates.some((candidate) => candidate.expression.includes("#queryInput")), true); assert.equal(candidates.some((candidate) => candidate.expression.includes("[name=")), true); });