- 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)
}