Weirdness when clicking span elements - html

I have a FAYT input I'm checking. I type in the textbox, see the options unfold and click one of them. All this passes neatly but there is something in the process that fails because the selected category is not selected. (this feature works like a charm when you try it manually)
This is the outline of the drop down suggestions' html:
<div id="suggestions">
<span name="span1" onclick="selectByClick()" onMouseOver="changeColor()">text1<span/>
<span name="span2" onclick="selectByClick()" onMouseOver="changeColor()">text2<span/>
</div>
What I'm doing is:
sel.click('//div[#id="suggestions"]//span[2]')
Ideas what could be causing this?

ok got it:
sel.mouse_over(xpath)
sel.click(xpath)

Related

Selenium IDE clicking checkbox doesn't work after downloading file

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.

Tracking Link Click on Google Tag Manager

I want to track clicks on the following button/link with Google Tag Manager. I created a trigger in Google Tag Manager that triggers when the element_id = 100. This works fine, except that when I click exactly on the text, it doesn't do anything, the link looks like a button, with the text in the middle of it. I can't change anything to the html or css, otherwise I can think of multiple things, so I need to find a solution without changing the html. Also, the 'myclass' class and the 'label' class get used in other elements.
<a class="myclass" id="100" href="http://www.url.com">
<span class="label">Text</span>
</a>
Anyone an idea?
Thanks a lot,
The following workaround worked:
Create trigger when element text contains "Text". This will trigger events on the button and the label on the button, of all buttons with "Text" as label.
Create tag for that trigger that checks with simple javascript if either the id of the current element = 100, which will happen when you click the button but not the label, or that the id of the parent = 100, which happens when you click the label. You can get the element that triggered the tag using the built-in variable "Click Element". Which you need to access the parent element.
Technically, you shouldn't have a CSS ID that starts with (or is) a number, so not sure if your code example is accurate or not. Whatever the case, you're probably better off using "matches CSS selector" so that you don't need to use any custom JS.
If indeed your HTML uses id="100", then the above will work. If it's anything else that doesn't start with a number, then you can use
#whatever > span

Rspec and Watir; locating and changing <span> text within a button element

I am playing around with rpsec and watir-webdriver, and am encountering a strange issue where I can click into a button, but I cannot interact with (or change) the text in the span inside. This is what the html looks like:
<button class="pure-button toggle-mode button-link edit-text-button-element" data-reactid=".0.1.0.1.1.0.0.0.0" title="Edit">
<span class="value false" data-reactid=".0.1.0.1.1.0.0.0.0.0">Untitled</span>
</span>
</button>
Right now my ruby code looks like this:
foo = #browser.button(:class, 'pure-button toggle-mode button-link edit-text-button-element')
foo.click
foo.span.set('Hello')
Running this gives me the initial error expected Hash or (:how, 'what'), got ["Hello"]
Any thoughts on what I'm doing wrong here?
Found a solution that works: after clicking to interact with the element, I was able to set text by using send_keys. So I did this:
foo = #browser.button(:class, 'pure-button toggle-mode button-link edit-text-button-element')
foo.click
#browser.send_keys {keystrokes simulated here}
That is because you cannot set text of the span in watir-webdriver. At least so easily. But if you will do for example:
puts foo.span.text
it will work. Here is the full list of what you can do with span: Usefull Link
Of course there is the way to change the text in your span:
browser.execute_script("arguments[0].textContent= 'Hello'", foo.span)
But I cannot imagine the situation when it will be really necessary for the real testing in a real world.
The class locator only accepts a single class.
If you need all of the classes for it to be unique do:
#browser.button(css: ".pure-button.toggle-mode.button-link.edit-text-button-element")

What is the default cursor icon for delete?

In the process of building an app and I was setting it up so when you hold the control key and click on a checkbox it would change to a remove (x) rather than an add (✓).
I am able to add a class to my element when the keydown occurs and remove it when the keyup occurs. I also have it working on the click, however the problem I'm running into is I want to show a delete/remove cursor.
I know we have default icons for many things including adding something, but I can't seem to find anything for deleting/removing. Does anyone have a valid method of showing delete, other than building your own icon? I would like to avoid this, as each browser/os has different icons. Thus far other than creating my own icon, it seems like no-drop might be my closest choice?
Is there something I'm missing, hopefully someone has a better method of handling this than I do that would work with chrome/IE/FF/safari?
https://developer.mozilla.org/en-US/docs/Web/CSS/cursor
.add-item { cursor: copy; }
.remove-item { cursor: ????; }
There isn't one but you can create your own icon and use cursor: url(); CSS to accomplish this.
More info here: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_User_Interface/Using_URL_values_for_the_cursor_property
Example:
div {
cursor: url("https://i.stack.imgur.com/bUGV0.png"), auto;
}
<div>Hover Here</div>
not-allowed is the only one that makes sense, however the custom jpg url option looks pretty simple.
You could also rethink your UI design to get around this. You could just stick with the intuitive default behavior of a checkbox, and let the user click it with the understanding that the checkmark will toggle. No fancy control key, no fancy cursors. Maybe just a pointer icon in either case. With some separate add / remove action buttons.
You could also think about showing some clickable icons for add / remove (per item if applicable). Thus not using a checkbox.
Here is a list of cursor properties.
cursor: not-allowed seems to be the only one similar to a "deleted" property. Example.
You can also use the url property to insert your own custom image.
There are multiple options to get the expected result.
However it's not the default option, using cursor: url() to display a custom image should work fine.
Otherwise use one of the default properties, of which not-allowed is probably the best option.
More about cursor properties
Default cursors:
<p>Mouse over the words to change the cursor.</p>
<span style="cursor:auto">auto</span><br>
<span style="cursor:crosshair">crosshair</span><br>
<span style="cursor:default">default</span><br>
<span style="cursor:e-resize">e-resize</span><br>
<span style="cursor:grab">grab</span><br>
<span style="cursor:help">help</span><br>
<span style="cursor:move">move</span><br>
<span style="cursor:n-resize">n-resize</span><br>
<span style="cursor:ne-resize">ne-resize</span><br>
<span style="cursor:nw-resize">nw-resize</span><br>
<span style="cursor:pointer">pointer</span><br>
<span style="cursor:progress">progress</span><br>
<span style="cursor:s-resize">s-resize</span><br>
<span style="cursor:se-resize">se-resize</span><br>
<span style="cursor:sw-resize">sw-resize</span><br>
<span style="cursor:text">text</span><br>
<span style="cursor:w-resize">w-resize</span><br>
<span style="cursor:wait">wait</span><br>
<span style="cursor:not-allowed">not-allowed</span><br>
<span style="cursor:no-drop">no-drop</span><br>
Source
I suggest no-drop or not-allowed .

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...