auto-webmcp 0.3.19 → 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.
@@ -1820,6 +1820,18 @@ function serializeFormData(form, params, fieldEls) {
1820
1820
  }
1821
1821
  return result;
1822
1822
  }
1823
+ function maybeConvertIsoDate(value, el) {
1824
+ const isoMatch = value.match(/^(\d{4})-(\d{2})-(\d{2})$/);
1825
+ if (!isoMatch)
1826
+ return value;
1827
+ if (el instanceof HTMLInputElement && el.type === "date")
1828
+ return value;
1829
+ const fieldHint = (el.name ?? el.id ?? "").toLowerCase();
1830
+ if (!/date/.test(fieldHint))
1831
+ return value;
1832
+ const [, year, month, day] = isoMatch;
1833
+ return `${month}/${day}/${year}`;
1834
+ }
1823
1835
  function fillElement(el, value) {
1824
1836
  if (el instanceof HTMLInputElement) {
1825
1837
  const type = el.type.toLowerCase();
@@ -1834,7 +1846,7 @@ function fillElement(el, value) {
1834
1846
  el.dispatchEvent(new Event("change", { bubbles: true }));
1835
1847
  }
1836
1848
  } else {
1837
- setReactValue(el, String(value ?? ""));
1849
+ setReactValue(el, maybeConvertIsoDate(String(value ?? ""), el));
1838
1850
  }
1839
1851
  } else if (el instanceof HTMLTextAreaElement) {
1840
1852
  setReactValue(el, String(value ?? ""));
@@ -1888,16 +1900,48 @@ function getMissingRequired(metadata, params) {
1888
1900
  return [];
1889
1901
  return metadata.inputSchema.required.filter((fieldKey) => !(fieldKey in params));
1890
1902
  }
1903
+ function queryShadowAll(root, selector) {
1904
+ const results = [];
1905
+ const hosts = Array.from(root.querySelectorAll?.("*") ?? []);
1906
+ for (const host of hosts) {
1907
+ const sr = host.shadowRoot;
1908
+ if (!sr)
1909
+ continue;
1910
+ results.push(...Array.from(sr.querySelectorAll(selector)));
1911
+ results.push(...queryShadowAll(sr, selector));
1912
+ }
1913
+ return results;
1914
+ }
1891
1915
  async function fillComboboxButton(el, value) {
1892
1916
  const text = String(value ?? "").trim();
1893
1917
  console.log("[auto-webmcp] fillComboboxButton: clicking button, value=", JSON.stringify(text));
1918
+ el.dispatchEvent(new PointerEvent("pointerdown", { bubbles: true, cancelable: true }));
1919
+ el.dispatchEvent(new MouseEvent("mousedown", { bubbles: true, cancelable: true }));
1894
1920
  el.dispatchEvent(new MouseEvent("click", { bubbles: true, cancelable: true }));
1921
+ const ariaControlsId = el.getAttribute("aria-controls");
1895
1922
  const listbox = await new Promise((resolve) => {
1896
- const deadline = Date.now() + 1e3;
1923
+ const deadline = Date.now() + 3e3;
1897
1924
  const poll = () => {
1898
- const candidate = document.querySelector('[role="listbox"]') ?? document.querySelector('[role="option"]')?.closest('[role="listbox"]') ?? null;
1899
- if (candidate) {
1900
- resolve(candidate);
1925
+ if (ariaControlsId) {
1926
+ const byId = document.getElementById(ariaControlsId);
1927
+ if (byId) {
1928
+ resolve(byId);
1929
+ return;
1930
+ }
1931
+ const inShadow = queryShadowAll(document.body, `#${CSS.escape(ariaControlsId)}`)[0] ?? null;
1932
+ if (inShadow) {
1933
+ resolve(inShadow);
1934
+ return;
1935
+ }
1936
+ }
1937
+ const lightCandidate = document.querySelector('[role="listbox"]') ?? document.querySelector('[role="option"]')?.closest('[role="listbox"]') ?? null;
1938
+ if (lightCandidate) {
1939
+ resolve(lightCandidate);
1940
+ return;
1941
+ }
1942
+ const shadowCandidate = queryShadowAll(document.body, '[role="listbox"]')[0] ?? null;
1943
+ if (shadowCandidate) {
1944
+ resolve(shadowCandidate);
1901
1945
  return;
1902
1946
  }
1903
1947
  if (Date.now() >= deadline) {
@@ -1909,11 +1953,13 @@ async function fillComboboxButton(el, value) {
1909
1953
  poll();
1910
1954
  });
1911
1955
  if (!listbox) {
1912
- console.warn("[auto-webmcp] fillComboboxButton: listbox did not appear after 1s");
1956
+ console.warn("[auto-webmcp] fillComboboxButton: listbox did not appear after 3s");
1913
1957
  return;
1914
1958
  }
1915
- const options = Array.from(listbox.querySelectorAll('[role="option"]'));
1916
- console.log("[auto-webmcp] fillComboboxButton: listbox has", options.length, "options");
1959
+ const lightOptions = Array.from(listbox.querySelectorAll('[role="option"]'));
1960
+ const shadowOptions = queryShadowAll(listbox, '[role="option"]');
1961
+ const options = lightOptions.length > 0 ? lightOptions : shadowOptions;
1962
+ console.log("[auto-webmcp] fillComboboxButton: listbox has", options.length, "option(s)");
1917
1963
  const lowerValue = text.toLowerCase();
1918
1964
  const match = options.find((opt) => {
1919
1965
  const dataValue = (opt.getAttribute("data-value") ?? "").toLowerCase();
@@ -1922,14 +1968,16 @@ async function fillComboboxButton(el, value) {
1922
1968
  return dataValue === lowerValue || ariaLabel === lowerValue || optText === lowerValue;
1923
1969
  });
1924
1970
  if (match) {
1925
- console.log("[auto-webmcp] fillComboboxButton: clicking option", match.textContent?.trim());
1971
+ console.log("[auto-webmcp] fillComboboxButton: selecting option", match.textContent?.trim());
1972
+ match.dispatchEvent(new PointerEvent("pointerdown", { bubbles: true, cancelable: true }));
1973
+ match.dispatchEvent(new MouseEvent("mousedown", { bubbles: true, cancelable: true }));
1926
1974
  match.dispatchEvent(new MouseEvent("click", { bubbles: true, cancelable: true }));
1927
1975
  } else {
1928
1976
  console.warn(
1929
1977
  "[auto-webmcp] fillComboboxButton: no option matched",
1930
1978
  JSON.stringify(text),
1931
1979
  "available:",
1932
- options.map((o) => o.textContent?.trim())
1980
+ options.map((o) => o.getAttribute("data-value") ?? o.textContent?.trim())
1933
1981
  );
1934
1982
  }
1935
1983
  }