Using the Selenium IDE in Chrome I am making a test for a process on a website.
I have a website, where I need to click a checkbox to accept the terms of use, privacy terms etc. after the login. I can check those boxes without a problem through Selenium, but I can't check the box for the client terms. I have to download those first, what works without a problem. Selenium then doesn't check the accept box though.
I am using the whole xpath and when I tell Selenium to show me the element in the website, it shows me the correct one. I copied the xpath directly out of Chrome. I'm using following command.
Command: click
Target: xpath=/html/body/div[1]/div[2]/main/div/div[3]/div[3]/div[3]/label
I also tried following other targets, none of them worked. Nevertheless Selenium always showed the right label when I clicked the option "Find Target in Page".
css=.terms-client label
xpath=//div[3]/div[3]/label
xpath=//label[contains(.,'Ich akzeptiere die Prüfungsbestimmungen')]
I tried check instead of click too, what didn't work. This is the HTML-code of the affected element, after the client terms have been downloaded already.
<div class="terms-client card" ng-repeat="role in data.roles" style="">
<div class="header">Kandidat/-in: Elektroniker/in EFZ CH</div>
<div class="content">
<p ng-bind-html="(role.description || ('terms.client.terms'|trans))|nl2br">Bitte studieren Sie die Prüfungsbestimmungen sorgfältig.</p>
<span iv-ipa-dokument="role.url" btn-class="btn-fill" download-state="role.downloaded" btn-label="Bestimmungen herunterladen"><button ng-click="download(url)" class="btn btn-fill" ng-disabled="disabled"><i class="icon icon-check-square-o" ng-class="class"></i> Bestimmungen herunterladen</button></span>
</div>
<div class="accept">
<!---->
<input id="client-accept-0" class="checkbox-new client-accept ng-pristine ng-untouched ng-valid ng-empty" type="checkbox" ng-model="role.state" ng-disabled="!data.agb || role.accepted || !role.downloaded">
<label for="client-accept-0">Ich akzeptiere die Prüfungsbestimmungen</label>
<!---->
</div>
</div>
The label at the end is the part I would like to click. I don't understand why Selenium is able to check the other boxes and accept those terms, but not this one.
I noticed, the issue is, that the click stops working after downloading the terms. Before that it works.
I think the issue is the locator being used to locate the checkbox. With the information provided, I guess the click event isn't handled for the label used.
Instead of getting the XPATH of the label, you need to select the input tag of the checkbox you need to click.
In this case the xpath of the element to select should be :
//label[contains(.,'Ich akzeptiere die Prüfungsbestimmungen')]/../input
Clicking using this element selector should perform the intended click.
I didn't find a proper solution but a workaround. A simple reload of the page after the download managed to solve my issue.
Related
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.
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:)).
I am using headless chrome, rspec - 3.6.0, capybara - 2.15.1
select('apple',from: 'fruits', visible: false)
page.find('#apple', visible: false).click
within 'results' do
page.find('.option', text: 'apple').click
end
Error:
Capybara::ElementNotFound: Unable to find visible css "#fruits .chosen-drop .chosen-results"
The error shown in your question is not from any of the other lines of code you show, however based on the error message it's pretty clear what's going on.
Attempting to perform any action on an element you've found using visible: false makes no sense because the user can't interact with a non-visible element (99% of time if you specify visible: false you're doing something wrong). In the current case you are using the chosen library which hides the normal HTML <select> element and replaces it with a JS driven widget made up of <ul> and <li> elements. Because of this you can't use the normal select method and instead need to interact with the page just like a normal user would (click on the 'chosen' field and then click on the element from the list). You haven't provided the actual HTML generated for your page, but based on your attempts and the output generated by the chosen demo page - https://harvesthq.github.io/chosen/ - it will be something like
<select id="fruits" ... style="display: none;>
...
</select>
<div class="chosen-container" ... >
...
<div class="chosen-drop">
...
<ul class="chosen-results">
<li ...>Apple</li>
<li ...>Orange</li>
...
</ul>
</div>
</div>
So to work with that the user would first need to click on the .chosen-conatiner element (sibling of the hidden select) to open the .chosen-drop element and then click on the correct <li> from the .chosen-results element which translates into something like
chosen_container = find('select#fruits + .chosen-container').click
chosen_container.find('.chosen-results li', exact_text: 'Apple').click
If that doesn't work for you then you'll need to add the exact HTML from your live page to your question.
Note: if you're dealing with a lot of chosen widgets in your site you may want to look into writing custom Capybara selectors -https://www.rubydoc.info/github/teamcapybara/capybara/Capybara#add_selector-class_method - to make the tests read a lot better
So I'm trying to hit this "Review Agreement" button:
which has the following html code:
<section class="col-33 text-right">
<button class="anchor-button bordered" ng-click="onClickReviewAgreement()">Review Agreement</button>
</section>
BUT apparently it's loaded from another resource, so findElement(By.*) doesn't work on it - I've also tried By.xpath("/html/body/ul/li[2]/notification-bar/ul/li/section[1]/section[2]/button")-. All the related code I'm getting in View Page Sources is:
<!-- Agreement form modal -->
<ui-modal
ui-modal-id="ui.modals.agreementFormModal"
ui-modal-class="takeover agreement"
ui-modal-controller="AgreementFormController"
ui-modal-template-url="paths.templates + '/components/forms/tpl.agreement-form.html'"
ui-modal-has-dimmer="true">
</ui-modal>
Is there any way I can select these kinds of elements?
You should be able to bind to ng-click="onClickReviewAgreement()" using css. It should be unique and css is a better and more efficient alternative to xpath
Try using css to find the element and click thereafter -
WebElement buttonElement = driver.findElement(By.cssSelector('[ng-click="onClickReviewAgreement()"]'));
buttonElement.click();
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...