Puppeteer can't distinguish between two selectors with same ID - puppeteer

I have a puppeteer implementation I'm working on to fill out a form on a website that (sadly) doesn't offer an API.
Everything goes great until I use this code to click the second button on a list of buttons:
await page.click('#calculateCharge'); // open the set values dialog
Reason being, the #calculateCharge id is used multiple times on the page, like this:
<button id="calculateCharge" type="button" name="amount" class="btn btn--secondary btn--full-mobile btn--full "><span>$ 80.00</span></button>
<button id="calculateCharge" type="button" name="amount" class="btn btn--secondary btn--full-mobile btn--full "><span>$ 35.00</span></button>
<button id="calculateCharge" type="button" name="amount" class="btn btn--secondary btn--full-mobile btn--full "><span>$ 42.00</span></button>
Puppeteer clicks the first button every time because whoever wrote the HTML didn't id the buttons dynamically. The ids are all the same, so I don't know how to access the 2nd or third buttons. I also don't have access to the HTML source (not my page), so I can't fix it from the other side.
Any ideas?

I solved my issue by using xPaths instead of ids.
First, right click on the button in your browser and click inspect. In the inspector's HTML tree, right click on the highlighted HTML and copy the full xPath.
Second, set the element as a variable using the copied xPath. Note the x after the $.
let butt = await page.$x('xPath')
Last, click the button by referencing the first position of the variable's array.
await butt[0].click()
Copy/paste from my production file:
let butt = await page.$x('/html/body/div[1]/div/main/div[1]/div[2]/div[2]/div/div/div/form/div[1]/div[2]/table/tbody/tr[5]/td[2]/div/div/button');
await butt[0].click();

Related

Using Font Awesome Unicode with Coldfusion

I have an HTML input button in my ColdFusion application that is submitting a form. I am trying to include a Font Awesome icon along with the text of the button. The only way I can specify the Unicode without throwing an error is to double out the hash character.
<input class="stylized_btn" tabindex="0" type="submit" name="save2"
id="save2" value=" &##xf0c7; Save This Ticket"
onclick="disableSaveButtonClick(event);" />
However, instead of showing the icon, it just shows a square.
This seems like it's a quirk with ColdFusion not recognizing my Unicode character because of the double hashtag, but that's just a guess. I have other button elements on my page that are properly displaying the Font Awesome icons correctly, so I know it is not an issue with my font definition. I am unsure where exactly I am going wrong here. Can anyone help shed some light?
Updated code using button tag instead.
HTML button
<button id="saveOnlyButton" name="save" class="stylized_btn">
<i class="fas fa-save"> </i> Update Ticket
</button>
JavaScript
window.onload=function(){
var SaveButton = document.getElementById("saveOnlyButton");
SaveButton.addEventListener("click", disableSaveButton);
}
//Save Button Logic
function disableSaveButton() {
console.log("Save button clicked");
document.getElementById("submitType").value = "save";
document.getElementById("saveOnlyButton").innerHTML = "Please Wait...";
document.getElementById("saveOnlyButton").disabled = true;
document.getElementById("autoSumForm").submit();
}
Have you tried using a BUTTON tag? (We stopped using input:submit buttons.)
We usually use <button type =“submit”><i class=“fa fa-lg fa-my-icon”></i > Label Text</button>, but you should be able to use the HTML entity.
Instead of using an input element, use a button. The default behavior of a button is to submit a form.
<button class="stylized_btn btn-default" tabindex="0" id="save2" onclick="disableSaveButtonClick(event);"><i class="fa fa-save"></i> Save This Ticket</button>
(I added btn-default in case you're using bootstrap)
It's not a quirk in ColdFusion as you suggest. ColdFusion is behaving exactly as intended. The reason why you need a double hash ## is because whenever you are in a <cfoutput> tag, ColdFusion sees the single hash # as the start of a variable or evaluable expression. When it doesn't find the closing hash, it throws an error.
Now there are times when your intent is to use the hash for display purposes and not to evaluate a variable or expression, as it is in your case. So the solution is to use the double hash ## an an escape character to let CF know you want to just display it as a single hash on the rendered page.
If you use your browser's developer tools and inspect element, it shold appear to correctly display as a single hash. The other fix to your issue is to make sure you remove the section of code with the input button from being inside a <cfoutput> block.
Most importantly, you shouldn't be debugging by looking at the CF source code, you should debug this looking at the rendered page by using your browser's developer tools or the browser's "view source" option. If you can, please update your original question by providing a screenshot of the "inspect element" of your submit button.

form - enable middle click on submit button (using pure html only!)

I have 4 links. Previously implemented as A tags.
My goal is to switch the request method (GET) with POST. Everything else have to remain the same!
The problem - it must be implemented using pure HTML - to be exact - no ajax and no window.open().
My solution is half way there. Hopefully to get a creative second half from you (impossible is also an answer)
Here is the (simplified) HTML:
<form
id = "resultsForm"
target="_blank"
action="http://example.com"
method="post"
>
<input type="hidden" name="data" value="someData">
<button type="submit" value="submit">
<p class="contextual"> title </p>
<span></span>
</button>
</form>
Now, it looks and feels like the old implementation and also sends POST requests
But - contrary to a link - a button can't be middle clicked or opened in new window when right clicking on it (by default...)
Can I somehow wrap it in an A tag to achieve the explained behavior without using js events or be conflicted with form subbmission?
Your help is really appreciated
No, this is impossible.
Anchor elements cannot contain interactive elements such as button elements.
Forms should be posted to the target window, so a normal click on the submit button, by virtue of the _blank value, should open an unnamed browsing context (a new window or tab).
Users should be accustomed to not middle-clicking on buttons, although there is a habit of developers to style links to look like buttons, throwing off users' expectations (end rant:)).

Bootstrap single file upload and submission button

I am trying to make a button on user profile that will allow the user to choose file and after the file has been chosen, it will be uploaded with the same button.
I want the button appearance as that defined by the code below:
<button class="btn btn-primary form-control"><span class='glyphicon glyphicon-camera'></span> Change Photo</button>
I want to change it into:
<input type='Image' onchange="this.form.submit()"/>
But with bootstrap classes and <span class='glyphicon glyphicon-camera'></span> Change Photo instead of 'submit' text on button.
How can I do it?
If you just want to change the text text inside of the button you can use JavaScripts innerHTML function to set the value, but you will have to include the span.
button = getElementsByClassName("btn btn-primary form-control")[0];
button.innerHTML="<span class='glyphicon glyphicon-camera'></span> Change Photo";
This assumes that you only have one object with that exact class on the page. If you have more you will have to add the logic to select the correct button.
If you need to do something with the file that is loaded you will need to have some sort of server side language or scripting language since this can not be done in HTML and CSS alone.

Form enter key action with lists and AngularJS

In my AngularJS project I have an account details page where you can change your personal account information. This page allows for multiple phone numbers and e-mailaddresses to be supplied. Using mouse input (or tabbing to buttons and pressing them with space bar) works perfectly, however I'd like to add the convenience of the enter key pressing the 'logical' buttons.
My form looks like (accidentally forgot to translate a few items):
A simplified version of the HTML for the form can be found on PasteBin, I've mainly removed the directives for managing the lists.
All buttons are <button> elements except for the cancel button which an <a> to the previous page, and the submit button is <button type="submit">.
When selecting any text box and pressing enter, the first (non-disabled) <button> element is 'clicked'. Meaning if I would change the last name, hit enter, the first phone number would be removed.
When you're in a new entry of phone numbers or e-mailaddresses (the row with the green + button) it should click that button, and if it's disabled do nothing.
When you're in any other text box on the form it should hit the save button, and also if the save button's disabled, do nothing.
Both buttons will be disabled based on form validation.
There'd be no trouble in changing the type of a button from button to submit if that'd help.
I would preferably have an all HTML solution, using just semantics, but I doubt that's really possible. So the logical alternative would be to use an AngularJS directive.
Please do not provide a jQuery or plain JavaScript solution relying on IDs or something like that. I don't want to hack my way around AngularJS, rather embrace it.
In the meantime I've worked on a directive that allows me to declare what I've called 'submit scopes'.
In essence you have actions (inputs) and targets (buttons), they're bound through a service by a key you can assign in the template. To avoid keys from clashing and from simple annoying work you can create a submit-scope which will cause it's children to prepend a unique key to the value they're accessing.
Within a submit-scope you can still override an action to use a global key instead by setting the attribute global-submit="true".
Example code:
<div submit-scope>
<input type="text" submit-action />
<button type="button" submit-target>Pressing enter in the above field will click this button.</button>
</div>
You can view the entire source code and a slightly larger example on Plnkr.
I just tried to replace
<button>Cancel</button>
with
<input type="button" value="Cancel">
and it seems to work correctly...

HTML Input Button

I'm using this code here:
<input type="button" value="Latest Results" onClick="self.location='http://URL.COM/SEARCH STRING'+document.getElementById('code').value +'EXTRA BIT OF SEARCH URL'">
Which I'm using with an input box (sometime several input boxes) to take an input and quickly add it to a URL to search an internal system. It works great for what we need, but I'm trying to get it to open in a new window rather than the current one.
I've tried adding target="_blank" to the end and changing onClick="self.location= to window.open but no luck.
Try this:
<input type="button" value="Latest Results" onClick="window.open('http://www.google.com');">
Use window.open instead of self.location :)
jsBin.