auto-webmcp 0.3.20 → 0.3.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1874,16 +1874,48 @@ function getMissingRequired(metadata, params) {
1874
1874
  return [];
1875
1875
  return metadata.inputSchema.required.filter((fieldKey) => !(fieldKey in params));
1876
1876
  }
1877
+ function queryShadowAll(root, selector) {
1878
+ const results = [];
1879
+ const hosts = Array.from(root.querySelectorAll?.("*") ?? []);
1880
+ for (const host of hosts) {
1881
+ const sr = host.shadowRoot;
1882
+ if (!sr)
1883
+ continue;
1884
+ results.push(...Array.from(sr.querySelectorAll(selector)));
1885
+ results.push(...queryShadowAll(sr, selector));
1886
+ }
1887
+ return results;
1888
+ }
1877
1889
  async function fillComboboxButton(el, value) {
1878
1890
  const text = String(value ?? "").trim();
1879
1891
  console.log("[auto-webmcp] fillComboboxButton: clicking button, value=", JSON.stringify(text));
1892
+ el.dispatchEvent(new PointerEvent("pointerdown", { bubbles: true, cancelable: true }));
1893
+ el.dispatchEvent(new MouseEvent("mousedown", { bubbles: true, cancelable: true }));
1880
1894
  el.dispatchEvent(new MouseEvent("click", { bubbles: true, cancelable: true }));
1895
+ const ariaControlsId = el.getAttribute("aria-controls");
1881
1896
  const listbox = await new Promise((resolve) => {
1882
1897
  const deadline = Date.now() + 3e3;
1883
1898
  const poll = () => {
1884
- const candidate = document.querySelector('[role="listbox"]') ?? document.querySelector('[role="option"]')?.closest('[role="listbox"]') ?? null;
1885
- if (candidate) {
1886
- resolve(candidate);
1899
+ if (ariaControlsId) {
1900
+ const byId = document.getElementById(ariaControlsId);
1901
+ if (byId) {
1902
+ resolve(byId);
1903
+ return;
1904
+ }
1905
+ const inShadow = queryShadowAll(document.body, `#${CSS.escape(ariaControlsId)}`)[0] ?? null;
1906
+ if (inShadow) {
1907
+ resolve(inShadow);
1908
+ return;
1909
+ }
1910
+ }
1911
+ const lightCandidate = document.querySelector('[role="listbox"]') ?? document.querySelector('[role="option"]')?.closest('[role="listbox"]') ?? null;
1912
+ if (lightCandidate) {
1913
+ resolve(lightCandidate);
1914
+ return;
1915
+ }
1916
+ const shadowCandidate = queryShadowAll(document.body, '[role="listbox"]')[0] ?? null;
1917
+ if (shadowCandidate) {
1918
+ resolve(shadowCandidate);
1887
1919
  return;
1888
1920
  }
1889
1921
  if (Date.now() >= deadline) {
@@ -1895,11 +1927,13 @@ async function fillComboboxButton(el, value) {
1895
1927
  poll();
1896
1928
  });
1897
1929
  if (!listbox) {
1898
- console.warn("[auto-webmcp] fillComboboxButton: listbox did not appear after 1s");
1930
+ console.warn("[auto-webmcp] fillComboboxButton: listbox did not appear after 3s");
1899
1931
  return;
1900
1932
  }
1901
- const options = Array.from(listbox.querySelectorAll('[role="option"]'));
1902
- console.log("[auto-webmcp] fillComboboxButton: listbox has", options.length, "options");
1933
+ const lightOptions = Array.from(listbox.querySelectorAll('[role="option"]'));
1934
+ const shadowOptions = queryShadowAll(listbox, '[role="option"]');
1935
+ const options = lightOptions.length > 0 ? lightOptions : shadowOptions;
1936
+ console.log("[auto-webmcp] fillComboboxButton: listbox has", options.length, "option(s)");
1903
1937
  const lowerValue = text.toLowerCase();
1904
1938
  const match = options.find((opt) => {
1905
1939
  const dataValue = (opt.getAttribute("data-value") ?? "").toLowerCase();
@@ -1908,14 +1942,16 @@ async function fillComboboxButton(el, value) {
1908
1942
  return dataValue === lowerValue || ariaLabel === lowerValue || optText === lowerValue;
1909
1943
  });
1910
1944
  if (match) {
1911
- console.log("[auto-webmcp] fillComboboxButton: clicking option", match.textContent?.trim());
1945
+ console.log("[auto-webmcp] fillComboboxButton: selecting option", match.textContent?.trim());
1946
+ match.dispatchEvent(new PointerEvent("pointerdown", { bubbles: true, cancelable: true }));
1947
+ match.dispatchEvent(new MouseEvent("mousedown", { bubbles: true, cancelable: true }));
1912
1948
  match.dispatchEvent(new MouseEvent("click", { bubbles: true, cancelable: true }));
1913
1949
  } else {
1914
1950
  console.warn(
1915
1951
  "[auto-webmcp] fillComboboxButton: no option matched",
1916
1952
  JSON.stringify(text),
1917
1953
  "available:",
1918
- options.map((o) => o.textContent?.trim())
1954
+ options.map((o) => o.getAttribute("data-value") ?? o.textContent?.trim())
1919
1955
  );
1920
1956
  }
1921
1957
  }