HARPA.AI
LIBRARYAPIGUIDESAI COMMANDSBLOG

🧭  Click Anything By Text

Finds and clicks any clickable element on the page by searching its text content

Created by Morteza
Updated on Feb 2, 19:01
Installed 11 times
RUNS JS CODE

How to Use

IMPORT COMMAND

Content

- type: ask
  param: text
  message: 'Please provide the text of the clickable element:'
  options:
    - label: 🔃 AUTO-TEST
      value: auto
    - $custom
  default: ''
  vision:
    enabled: false
    mode: area
    hint: ''
    send: true
  label: HYPERLINK TEXT
  optionsInvalid: false
- type: calc
  func: set
  param: amount
  format: ''
  value: '5'
  label: SET AMOUNT
  condition: '{{text}} = auto'
- type: js
  args: amount
  code: |-
    // Takes the number as an argument
    function createArray(amount) {
     // Array mit amount Elementen erstellen
     const data = Array(amount).fill(null);
     return data;
    }

    // Get with args.amount
    return createArray(args.amount);
  param: list
  timeout: 15000
  onFailure: SHOW THE STATUS
  silent: true
  label: LOOP LENGTH
  condition: '{{text}} = auto'
- type: loop
  list: list
  steps:
    - type: gpt
      prompt: >-
        Analyze [SCREENSHOT], replacing this placeholder with the actual
        screenshot {{view}}. Identify ONE, and ONLY ONE, *NEW* clickable element
        within the screenshot. "Clickable" means an element a user could
        interact with, such as a button, link, or selectable text.  Do NOT
        select an element that has been selected before.


        Guidelines for Selection:


        1. Prioritize Simplicity: Favor elements with fewer nested elements or
        components (children). Choose the simplest clickable element if multiple
        options are present.

        2. Exclusion Criteria:  Disregard any element whose visible text
        contains the words "logout," "delete," "remove," or "sign out."


        Output Instructions:


        * If the selected element is a link leading to a different webpage,
        output ONLY the link's full target URL (web address).  Do not include
        any other text or descriptions.

        * If the selected element is NOT a link (e.g., a button, interactive
        text), output ONLY the visible text displayed on that element.  Do not
        provide any other information or context.


        If no new clickable elements are available, output "NO NEW CLICKABLE
        ELEMENTS FOUND".



        Example:

        If the screenshot shows a button labeled "Submit" and a link to
        "https://www.example.com," and "Submit" has already been selected, the
        correct output for the link would be: https://www.example.com



        Remember: Output ONLY the text or URL of the SINGLE, *NEWLY* chosen
        element.  Nothing else.


        You should not output this now: {{search}}
      param: search
      silent: false
      label: GENERATE CLICKABLE ELEMENT TEXT
    - type: wait
      for: custom-delay
      silent: true
      delay: '1500'
    - type: js
      args: search, selector
      code: |-
        function nuclearClickStorm(search) {
          const clicked = new WeakSet();

          const quantum = {
            harvest: (root) => {
              const isInteractive = (el) => {
                const style = getComputedStyle(el);
                return style.pointerEvents !== 'none' && style.cursor === 'pointer';
              };
              const grinder = [...root.querySelectorAll('*')].filter(isInteractive);

              root.querySelectorAll('*').forEach(el => {
                if (el.shadowRoot) grinder.push(...quantum.harvest(el.shadowRoot));
              });

              return grinder.filter(el => {
                const rect = el.getBoundingClientRect();
                return el.offsetWidth + el.offsetHeight > 0 &&
                       rect.top >= 0 &&
                       rect.left >= 0 &&
                       rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
                       rect.right <= (window.innerWidth || document.documentElement.clientWidth);
              });
            },

            textSingularity: (el) => {
              const extractNestedText = (node) => {
                if (node.nodeType === Node.TEXT_NODE) return node.textContent;
                return Array.from(node.childNodes).map(extractNestedText).join('|');
              };

              return [
                extractNestedText(el),
                el.title,
                el.getAttribute('aria-label'),
                el.value,
                el.placeholder
              ].filter(t => t).join('|').replace(/\s+/g, ' ').trim();
            },

            triggerApocalypse: (el) => {
              if (clicked.has(el)) return;
              clicked.add(el);

              try {
                const linkEl = el.tagName === 'A' ? el : el.closest('a');
                if (linkEl && linkEl.href) {
                  const href = linkEl.getAttribute('href');
                  if (href) {
                    if (!href.startsWith('http')) {
                      const fullUrl = href.startsWith('/') ? window.location.origin + href : window.location.origin + '/' + href;
                      window.location.replace(fullUrl);
                    } else {
                      window.location.href = href;
                    }
                    return;
                  }
                }

                const rect = el.getBoundingClientRect();
                const centerX = rect.left + rect.width / 2;
                const centerY = rect.top + rect.height / 2;

                el.dispatchEvent(new MouseEvent('click', {
                  bubbles: true,
                  composed: true,
                  view: window,
                  cancelable: true,
                  clientX: centerX,
                  clientY: centerY,
                  buttons: 1
                }));

                el.scrollIntoViewIfNeeded?.();

              } catch (e) {
                console.error('Quantum disruption:', e);
              }
            },

            executeOrder66: () => {
              const searchStr = String(search).trim();
              if (!searchStr) return { casualties: 0, survivors: 0, message: 'NO SEARCH TEXT PROVIDED' };

              const elements = quantum.harvest(document)
                .filter(el => {
                  const text = quantum.textSingularity(el).toLowerCase();
                  try {
                    return text.includes(searchStr.toLowerCase()) &&
                           !/(logout|delete|remove|sign\s*out)/i.test(text);
                  } catch (e) {
                    return false;
                  }
                })
                .sort((a, b) => a.children.length - b.children.length);

              if (elements.length > 0) {
                quantum.triggerApocalypse(elements[0]);
              }

              return {
                casualties: elements.length > 0 ? 1 : 0,
                survivors: document.querySelectorAll('*').length - (elements.length > 0 ? 1 : 0),
                message: elements.length > 0 ? `TARGET ${searchStr.toUpperCase()} NEUTRALIZED` : `TARGET ${searchStr.toUpperCase()} NOT FOUND`
              };
            }
          };

          return quantum.executeOrder66();
        }

        return nuclearClickStorm(args.search);
      param: search
      timeout: 15000
      onFailure: SAY
      silent: true
      label: CLICK OR NAVIGATE TO HYPERLINK
    - type: say
      message: '{{search}}'
      label: SHOW THE STATUS
  condition: '{{text}} = auto'
  label: LOOP AUTO CLICK
- type: jump
  to: HYPERLINK TEXT
  condition: '{{text}} = auto'
- type: calc
  func: set
  param: search
  format: ''
  value: '{{text}}'
  label: SET CLICKABLE ELEMENT TEXT
- type: js
  args: search, selector
  code: |-
    function nuclearClickStorm(search) {
      const clicked = new WeakSet();

      const quantum = {
        harvest: (root) => {
          const isInteractive = (el) => {
            const style = getComputedStyle(el);
            return style.pointerEvents !== 'none' && style.cursor === 'pointer';
          };
          const grinder = [...root.querySelectorAll('*')].filter(isInteractive);

          root.querySelectorAll('*').forEach(el => {
            if (el.shadowRoot) grinder.push(...quantum.harvest(el.shadowRoot));
          });

          return grinder.filter(el => {
            const rect = el.getBoundingClientRect();
            return el.offsetWidth + el.offsetHeight > 0 &&
                   rect.top >= 0 &&
                   rect.left >= 0 &&
                   rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
                   rect.right <= (window.innerWidth || document.documentElement.clientWidth);
          });
        },

        textSingularity: (el) => {
          const extractNestedText = (node) => {
            if (node.nodeType === Node.TEXT_NODE) return node.textContent;
            return Array.from(node.childNodes).map(extractNestedText).join('|');
          };

          return [
            extractNestedText(el),
            el.title,
            el.getAttribute('aria-label'),
            el.value,
            el.placeholder
          ].filter(t => t).join('|').replace(/\s+/g, ' ').trim();
        },

        triggerApocalypse: (el) => {
          if (clicked.has(el)) return;
          clicked.add(el);

          try {
            const linkEl = el.tagName === 'A' ? el : el.closest('a');
            if (linkEl && linkEl.href) {
              const href = linkEl.getAttribute('href');
              if (href) {
                if (!href.startsWith('http')) {
                  const fullUrl = href.startsWith('/') ? window.location.origin + href : window.location.origin + '/' + href;
                  window.location.replace(fullUrl);
                } else {
                  window.location.href = href;
                }
                return;
              }
            }

            const rect = el.getBoundingClientRect();
            const centerX = rect.left + rect.width / 2;
            const centerY = rect.top + rect.height / 2;

            el.dispatchEvent(new MouseEvent('click', {
              bubbles: true,
              composed: true,
              view: window,
              cancelable: true,
              clientX: centerX,
              clientY: centerY,
              buttons: 1
            }));

            el.scrollIntoViewIfNeeded?.();

          } catch (e) {
            console.error('Quantum disruption:', e);
          }
        },

        executeOrder66: () => {
          const searchStr = String(search).trim();
          if (!searchStr) return { casualties: 0, survivors: 0, message: 'NO SEARCH TEXT PROVIDED' };

          const elements = quantum.harvest(document)
            .filter(el => {
              const text = quantum.textSingularity(el).toLowerCase();
              try {
                return text.includes(searchStr.toLowerCase()) &&
                       !/(logout|delete|remove|sign\s*out)/i.test(text);
              } catch (e) {
                return false;
              }
            })
            .sort((a, b) => a.children.length - b.children.length);

          if (elements.length > 0) {
            quantum.triggerApocalypse(elements[0]);
          }

          return {
            casualties: elements.length > 0 ? 1 : 0,
            survivors: document.querySelectorAll('*').length - (elements.length > 0 ? 1 : 0),
            message: elements.length > 0 ? `TARGET ${searchStr.toUpperCase()} NEUTRALIZED` : `TARGET ${searchStr.toUpperCase()} NOT FOUND`
          };
        }
      };

      return quantum.executeOrder66();
    }

    return nuclearClickStorm(args.search);
  param: search
  timeout: 15000
  onFailure: SAY
  silent: true
  label: CLICK OR NAVIGATE TO HYPERLINK
- type: say
  message: '{{search}}'
  label: SHOW THE STATUS
- type: jump
  to: HYPERLINK TEXT
Notice: Please read before using

This automation command is created by a community member. HARPA AI team does not audit community commands.

Please review the command carefully and only install if you trust the creator.

Contact us
HomeUse CasesGuidesPrivacy PolicyTerms of Service
CAN WE STORE COOKIES?
Our website uses cookies for the purposes of accessibility and security. They also allow us to gather statistics in order to improve the website for you. More info: Privacy Policy