- 1) Wait for page to load
 - 2) Prepend TODO to top of page
 - 3) Fill a text box only if the relevant label exists, do not cause an error
 - 4) Click dropdown and wait, then select option
 - 5) Chain actions together, by dependency
 - 6) Chain actions together, by time delay (without nesting hell)
 - 7) Find button by visible text (not by ID) using XPath
 - 8) Find text field by neighboring visible text (not by ID) using XPath
 - 9) Delete an obtrusive element
 - Others, less critical
 
window.addEventListener('load', function() {
    alert('page loaded')
}, false);function prependButton(text, onClick) {
  // Create the button element
  const button = document.createElement('button');
  // Set the button text
  button.textContent = text;
  // Add an onClick event listener
  button.addEventListener('click', onClick);
  // Prepend the button to the body
  document.body.prepend(button);
}if (elem = document.evaluate('//*[contains(text(), "Username or Library Card Number")]',document).iterateNext()) {
    elem.nextSibling.nextSibling.value = 'sarnobat';
}setTimeout(() => {console.log('pep related');                document.evaluate('//*[@aria-controls="dropdown-18"]',document,null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE).snapshotItem(0).click();}, startTime); startTime += interval;
setTimeout(() => {console.log('pep related');                document.querySelector("#No1").click();}, startTime); startTime += interval;setTimeout(() => {
    document.evaluate("//*/input[contains(@data-automation-id, 'name')]",document).iterateNext().value = "Sridhar Sarnobat";
    setTimeout(() => {
    document.evaluate("//*[text()='Save and Continue']",document).iterateNext().click();
    }, interval+buffer);
}, interval);Really long lines but it's easier to read repeatable lines
var startTime = 6000;
var interval = 1500;
setTimeout(() => {console.log('username');    document.evaluate('//*[contains(text(), "Username or Library Card Number")]',document).iterateNext().nextSibling.nextSibling.value = 'sarnobat'; }, startTime); startTime += interval;
setTimeout(() => {console.log('log in');    document.evaluate('//*[@value="Log In"]',document).iterateNext().click(); },                                                                        startTime); startTime += interval;Visible text is less fragile. DOM changes frequently
document.evaluate('//*[contains(text(), "Walmart Career Site")]',document).iterateNext().click()Visible text is less fragile.
- 
DOM changes frequently
 - 
ids are not always present
 - 
other attributes are not unique
document.evaluate('//*[contains(text(), "Username or Library Card Number")]',document).iterateNext().nextSibling.nextSibling.value = 'sarnobat'
 
document.evaluate('//*[contains(text(), "Stanford Careers")]',document).iterateNext().parentNode.parentNode.style.display = 'none'function fillTextField(id, text) {
            let element = document.evaluate(
                '//*[@id="'+id+'"]', document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE)
                .snapshotItem(0);
            setNativeValue(element, text);
            element.dispatchEvent(new Event('input', { bubbles: true }));
}
function setNativeValue(element, value) {
    const valueSetter = Object.getOwnPropertyDescriptor(element, 'value').set;
    const prototype = Object.getPrototypeOf(element);
    const prototypeValueSetter = Object.getOwnPropertyDescriptor(prototype, 'value').set;
    if (valueSetter && valueSetter !== prototypeValueSetter) {
        prototypeValueSetter.call(element, value);
    } else {
        valueSetter.call(element, value);
    }
}async function simulateMouseClick(el) {
    let opts = {view: window, bubbles: true, cancelable: true, buttons: 1};
    el.dispatchEvent(new MouseEvent("mousedown", opts));
    await new Promise(r => setTimeout(r, 50));
    el.dispatchEvent(new MouseEvent("mouseup", opts));
    el.dispatchEvent(new MouseEvent("click", opts));
}function fillDropdown(selectId, optionValue) {
                    var selectElement = document.evaluate(
                    '//*[@id="'+selectId+'"]', document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE)
                    .snapshotItem(0);
    var trigger2 = Object.getOwnPropertyDescriptor(
      window.HTMLSelectElement.prototype,
      "value"
    ).set;
    trigger2.call(selectElement, optionValue);
    var event2 = new Event("change", { bubbles: true });
    selectElement.dispatchEvent(event2);
}function toggleCheckbox(id) {
        const input = document.evaluate(
        '//*[@id="'+id+'"]', document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE)
        .snapshotItem(0);
    simulateMouseClick(input);
}function printFormFieldsIdByXpath() {
    var out = "";
    var out3 = "";
  // Get all form elements
  const forms = document.getElementsByTagName('form');
  // Loop through each form
  for (const form of forms) {
    // Get all input elements within the form using XPath
    const inputElements = document.evaluate(
      ".//input[@id]",
      form,
      null,
      XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
      null
    );
    // Loop through each input element and print its ID
    for (let i = 0; i < inputElements.snapshotLength; i++) {
      const element = inputElements.snapshotItem(i);
        if (element.type="text") {
        out += "id = " + element.id + "\t\taria-label=" + element.getAttribute("aria-label")+ "\tvalue = " +element.value+"\n";
        } else if (element.type="radio") {
        out3 += "[radio] id = " + element.id + "\t\taria-label=" + element.getAttribute("aria-label") +"\n";
        }
    }
}function printAllSelectOptionsByXpath() {
    // Get all select elements using XPath
    const selectElements = document.evaluate("//select", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
    // Loop through each select element
    for (let i = 0; i < selectElements.snapshotLength; i++) {
    const selectElement = selectElements.snapshotItem(i);
    // Get all option elements within the select element
    const options = selectElement.querySelectorAll("option");
var out = "";
    // Loop through each option element and print its text content
    for (const option of options) {
//      console.log(`Option: ${option.innerText}`);
//        out +=  selectElement.id
    }
    console.log(selectElement.id)
    var out2 = selectElement.id +  "\n========================\n";
    for (const option of options) {
        out2 += option.innerText + "\n";
    }
    //   +"\t\ttext = " + option.innerText +"\n";
    console.log(out2)
}