Reputation: 971
I know Selenium, Java/Python, XPaths etc and am looking for a basic "skeleton" Javascript bookmarklet that lets me perform simple Selenium like operations on the current page, e.g. (pseudocode),
begin
document.click ("//button[@class='buy']")
wait 2 seconds
document.entertext("//form[@class='name']", "John Smith")
wait 2 seconds
document.check("//radiobutton[@class='agrees']")
end
Googling returns an infinite number of articles but so far I haven't found anything that addresses this situation.
The reason for my request is that I enter the exact same (static) values in webforms day after day.
Upvotes: 0
Views: 383
Reputation: 136
Something like this? The code below can be saved into index.html, pressing a "Test" button simulates what you described — "buy" is clicked, then 2 seconds later the name is entered, and 2 seconds later "agree" is clicked.
<html><head><title>test</title></head>
<body>
<button class="test" onclick="myFunction()">Test</button>
<button class="buy" onclick="unhide_form()">Click me</button>
<form id="main_form" style="display: none">
<label for="fname">First name:</label><br>
<input class="name" type="text" id="fname" name="fname" value="" placeholder="Your name"><br>
<input type="radio" id="agrees" class="agrees" value="agr">
<label for="agrees">Agrees</label>
<input type="submit" value="Submit">
</form>
<script>
async function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function unhide_form() {
var f = document.getElementById("main_form")
f.style = "display: block"
}
async function myFunction() {
document.getElementsByClassName("buy")[0].click()
await sleep(2000)
document.getElementsByClassName("name")[0].value = "John"
await sleep(2000)
document.getElementsByClassName("agrees")[0].click()
}
</script>
</body></html>
Not sure if that'll be enough for the real task you're facing; if not, tell more details, like the URL of the site you're visiting, the automation steps (fields you're filling, buttons you're clicking, etc), and what exactly fails.
EDIT: I see. I'm new to doing this in javascript as well, so I also learned something new in the process :) Here's the code:
function submit_wayback_machine_form(url_to_save) {
elems = document.evaluate('//*[@id="web-save-url-input"]', document, null, XPathResult.ANY_TYPE, null );
elem = elems.iterateNext() //elem is now the text field
elem.value = url_to_save //changing its text to URL we want
elems = document.evaluate('//input[starts-with(@value, "SAVE PAGE")]', document, null, XPathResult.ANY_TYPE, null );
elem = elems.iterateNext()
elem.click()
}
submit_wayback_machine_form("https://google.com")
Tested it, appears to be working:
Also, here are the useful links I got the info from:
EDIT2:
Does Javascript not support something like element.click (Xpath)? Why the iteration and evaluation of everything?
That's just how it works, we document.evaluate(...) the XPATH expression first, and then we iterate through results (multiple elements may fit the same XPATH expression).
If I had to simplify it a bit for a more convenient usage... How about this?
//this one returns the first fitting element
function getFirstElementByXPATH(xpath) {
elems = document.evaluate(xpath, document, null, XPathResult.ANY_TYPE, null);
elem = elems.iterateNext()
return elem
}
//this one returns an array of fitting elements
function getAllElementsByXPATH(xpath) {
elems = document.evaluate(xpath, document, null, XPathResult.ANY_TYPE, null)
results = []
while (1) {
elem = elems.iterateNext()
if (elem != null) {
results.push(elem)
} else {
break
}
}
return results
}
Then, you can use
getFirstElementByXPATH("//li/div/button/span").click()
//or
getAllElementsByXPATH("//li/div/button/span")[0].click()
//or
element = getFirstElementByXPATH("//my_custom_expression_1")
element.click()
elements = getAllElementsByXPATH("//my_custom_expression_2")
elements[0].click()
elements[1].value = "abc"
Hopefully it's convenient enough!
Upvotes: 3
Reputation: 17903
Not a JS bookmarklet, but the Browserflow extension/service might be better to "enter the exact same (static) values in webforms day after day."
I used Browserflow to scrape data from paginated results that required clicking a button to append more results.
No JavaScript knowledge is required (although you can use JavaScript to do more complicated things if you want.)
Note this is a paid service with a limited free tier.
Upvotes: 0
Reputation: 54984
In general it looks like this:
(() => {
document.querySelector('.buy')?.click();
setTimeout(() => somethingElse(), 2000);
setTimeout(() => document.querySelector('.agrees')?.click(), 4000);
})()
But I can't tell what the something else is and it won't work if there's a navigation between steps
Upvotes: 1