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.
@@ -1794,6 +1794,18 @@ function serializeFormData(form, params, fieldEls) {
1794
1794
  }
1795
1795
  return result;
1796
1796
  }
1797
+ function maybeConvertIsoDate(value, el) {
1798
+ const isoMatch = value.match(/^(\d{4})-(\d{2})-(\d{2})$/);
1799
+ if (!isoMatch)
1800
+ return value;
1801
+ if (el instanceof HTMLInputElement && el.type === "date")
1802
+ return value;
1803
+ const fieldHint = (el.name ?? el.id ?? "").toLowerCase();
1804
+ if (!/date/.test(fieldHint))
1805
+ return value;
1806
+ const [, year, month, day] = isoMatch;
1807
+ return `${month}/${day}/${year}`;
1808
+ }
1797
1809
  function fillElement(el, value) {
1798
1810
  if (el instanceof HTMLInputElement) {
1799
1811
  const type = el.type.toLowerCase();
@@ -1808,7 +1820,7 @@ function fillElement(el, value) {
1808
1820
  el.dispatchEvent(new Event("change", { bubbles: true }));
1809
1821
  }
1810
1822
  } else {
1811
- setReactValue(el, String(value ?? ""));
1823
+ setReactValue(el, maybeConvertIsoDate(String(value ?? ""), el));
1812
1824
  }
1813
1825
  } else if (el instanceof HTMLTextAreaElement) {
1814
1826
  setReactValue(el, String(value ?? ""));
@@ -1862,16 +1874,48 @@ function getMissingRequired(metadata, params) {
1862
1874
  return [];
1863
1875
  return metadata.inputSchema.required.filter((fieldKey) => !(fieldKey in params));
1864
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
+ }
1865
1889
  async function fillComboboxButton(el, value) {
1866
1890
  const text = String(value ?? "").trim();
1867
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 }));
1868
1894
  el.dispatchEvent(new MouseEvent("click", { bubbles: true, cancelable: true }));
1895
+ const ariaControlsId = el.getAttribute("aria-controls");
1869
1896
  const listbox = await new Promise((resolve) => {
1870
- const deadline = Date.now() + 1e3;
1897
+ const deadline = Date.now() + 3e3;
1871
1898
  const poll = () => {
1872
- const candidate = document.querySelector('[role="listbox"]') ?? document.querySelector('[role="option"]')?.closest('[role="listbox"]') ?? null;
1873
- if (candidate) {
1874
- 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);
1875
1919
  return;
1876
1920
  }
1877
1921
  if (Date.now() >= deadline) {
@@ -1883,11 +1927,13 @@ async function fillComboboxButton(el, value) {
1883
1927
  poll();
1884
1928
  });
1885
1929
  if (!listbox) {
1886
- console.warn("[auto-webmcp] fillComboboxButton: listbox did not appear after 1s");
1930
+ console.warn("[auto-webmcp] fillComboboxButton: listbox did not appear after 3s");
1887
1931
  return;
1888
1932
  }
1889
- const options = Array.from(listbox.querySelectorAll('[role="option"]'));
1890
- 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)");
1891
1937
  const lowerValue = text.toLowerCase();
1892
1938
  const match = options.find((opt) => {
1893
1939
  const dataValue = (opt.getAttribute("data-value") ?? "").toLowerCase();
@@ -1896,14 +1942,16 @@ async function fillComboboxButton(el, value) {
1896
1942
  return dataValue === lowerValue || ariaLabel === lowerValue || optText === lowerValue;
1897
1943
  });
1898
1944
  if (match) {
1899
- 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 }));
1900
1948
  match.dispatchEvent(new MouseEvent("click", { bubbles: true, cancelable: true }));
1901
1949
  } else {
1902
1950
  console.warn(
1903
1951
  "[auto-webmcp] fillComboboxButton: no option matched",
1904
1952
  JSON.stringify(text),
1905
1953
  "available:",
1906
- options.map((o) => o.textContent?.trim())
1954
+ options.map((o) => o.getAttribute("data-value") ?? o.textContent?.trim())
1907
1955
  );
1908
1956
  }
1909
1957
  }