Clicking checkbox using capybara - ruby-on-rails

Currently I have a checkbox wrapped by a label.
<label for="exercise_form_division_ids_34">
<input class="check_boxes optional division-checkboxes" type="checkbox" value="34" name="form[division_ids][]" id="exercise_form_division_ids_34"> Technology
</label>
In my integration test I tried to use
within '.organizations' do
find("label[for='exercise_form_division_ids_34").click
end
OR
check "exercise_form_division_ids_#{department.id}", allow_label_click: true
But I still get this nable to find visible checkbox "calltree_exercise_form_division_ids_2" that is not disabled
Unable to find visible checkbox "exercise_form_division_ids_" that is not disabled

With the limited info provided you have a few potential possibilities.
The label/checkbox aren't actually inside an element with the class of the organizations on the page.
The error Unable to find visible checkbox "exercise_form_division_ids_" that is not disabled shows that no id is actually getting inserted into your selector which would tend to indicate that department isn't actually persisted in your test.
You may be assuming 34 is the correct id based on what it is in your dev environment but that may not be what it is in your test environment.
To narrow down the possibilities the first thing to do would be to grab a screenshot in your with test with page.save_and_open_screenshot (assuming you're using a driver which supports screenshots) and make sure there is actually a visible checkbox on the page. If not, you're probably not creating the required objects in the DB prior to your test starting.
Secondly look at the page in your browser and make sure the elements visible on the screen are actually the checkbox and/or the label. If both label & checkbox are being hidden and replaced with some JS widget then you'd need to interact with whatever elements the widget creates in the page (just like a user would). If only the checkbox is being hidden via JS/CSS but the label is visible then
check('Technology', allow_label_click: true) # check matching on label text
should work.

Related

AppiumLibrary for Robot Framework - Getting A Button's Text

I am experimenting with AppiumLibrary in RobotFramework and have a simple test for a requirement that states: "the Set button should exist on this page.". I am testing this by retrieving the button that has a specified ID and then checking if that button has the right text.
I am able to retrieve the button I want via ID however am having trouble getting the actual text on the button.
Here is how the button is defined on the web page:
<button id="button-set" class="button ng-binding" style="width: 20%">Set</button>
Very simple! Using Appium Desktop in web/hybrid app mode and clicking on the Set button it says the "text" attribute shows "Set". However I've learned that using the attributes in Appium Desktop arent valid when searching for elements on a webpage, for example searching by the Class attribute in Appium Desktop (android.widget.Button) is not correct because on the web page the class for the button is instead: "button ng-binding".
I have tried the following:
# this retrieves the button fine, by ID
PAGE SHOULD CONTAIN ELEMENT xpath=//button[#id="button-set"]
# these all return 'None'
${name}= GET ELEMENT ATTRIBUTE xpath=//button[#id="button-set"] name
${text}= GET ELEMENT ATTRIBUTE xpath=//button[#id="button-Set"] text
So, I am unsure which Attribute to use to retrieve the text when retrieving element by ID. Instead, I have tried to retrieve the element this way:
# this also passes fine - I feel like I should also make sure this button has the correct ID, to make the mapping
# between test procedures and cases easier, but if this is as good as it gets then
# this can be argued for
PAGE SHOULD CONTAIN ELEMENT xpath=//button[contains(text(),'set')]
# however, the following does not make sense, this returns "button" instead of "button-set", which makes me think the xpath query is not correct
${id2}= GET ELEMENT ATTRIBUTE xpath=//button[contains(text(),'set')] id
# again, both of these return 'None'
${name2}= GET ELEMENT ATTRIBUTE xpath=//button[contains(text(),'set')] name
${text2}= GET ELEMENT ATTRIBUTE xpath=//button[contains(text(),'set')] text
I have also tried the following:
${element}= GET WEBELEMENT xpath=//button[#id="button-set"]
# this returns "button-set" as you'd expect:
${id3}= GET ELEMENT ATTRIBUTE ${element} id
# these again return 'None'
${name3}= GET ELEMENT ATTRIBUTE ${element} name
${text3}= GET ELEMENT ATTRIBUTE ${element} text
I feel like this should be a very simple thing to do, and can see in other questions that you would use the Name attribute when using pure Appium. However, using the Robot Framework library instead, that these doesn't appear to be the right approach. I must be doing something pretty simple wrong here, can anyone point it out?
Thank you!
Stumbling across the same issue when trying to fetch element's attributes via Get Element Attribute keyword. It seems that when fetching for the element's text, your best bet is to use Get Text keyword. Switching to Get Text keyword solved the problem on my case. Please see the links below for further details. Spoiler: there aren't any real explanations as to why the Get Element Attribute is flaky.
https://serhatbolsu.github.io/robotframework-appiumlibrary/AppiumLibrary.html#Get%20Text
https://github.com/serhatbolsu/robotframework-appiumlibrary/issues/98

Capybara not seeing updates to the DOM made by Javascript

I'm running Rails 5.x, with, Cucumber, Siteprism and Capybara through chromedriver. Most things work except..
I have a tiny bit of javascript that changes the class on an element in response to an event. But Capybara never sees the change. It only ever sees the class the element has when the page initially loaded.
Using Chrome, and debugging my Cucumber steps, I can see the element has the new class, but Capybara doesn't see it.
This must be an issue other people have encountered and solved, though I can't find the right subject title.
example coffeescript
$(document).on('focus', 'tbody#item-entry > tr > td > input', (e) ->
$(#).closest('tr').addClass('focused-row')
$(#).closest('td').addClass('focused-cell')
)
example html after the focus event has been triggered
<tr class="focused-row">
<td>ignore this </td>
</tr>
The purpose is to change the background colour of the row containing an input element that has focus. It works.
But Capybara, can't see the class, but it can see any classes added when the page is loaded. e.g.
expect(siteprism_stuff.root_element['class']).to match(/focused-row/)
Ignore the SitePrism stuff, that just gets the right element. root_element is the Capybara class for the dom node.
Now I know it's getting the right Capybara element because if I change my view to put stuff in the class for each row, then it sees that perfectly OK. What it can't see is the any new class added via Coffeescript. Although it's visible in the Chrome inspector, and changes the background color of the focused row as required.
You're specifying an "ends with" CSS attribute selector ($=)
input[class$='form-control']
which since the class attribute for the element you're interested in
<input type="search" class="form-control form-control-sm" placeholder="" aria-controls="universitiesTable">
doesn't end with 'form-control' is correctly not matching. You probably just want to use a normal CSS class selector input.form-control if continuing to do it the way you are. Any of the following options should find the search field and fill in the data you are trying to fill in.
fill_in 'Search:', with: string
fill_in type: 'search', with: string
find(:field, type: 'search').set(string)
find('input.form-control').set(string)
Note: Your question is still unclear as to whether you are seeing the class added in the inspector in test mode, and whether the line color is changing while the tests are running (or whether you're only seeing that in dev mode) - This answer assumes the JS is actually running in test mode and you're seeing the line color change while the tests are running.
You don't show how you're actually triggering the focus event but I'll assume you're clicking the element. The thing to understand when working with Capybara is that the browser works asynchronously, so when something like click has been done, the actions triggered by that click have not necessarily been done yet. Because of that, whenever doing any type of expectation with page elements you should always be using the matchers provided by Capybara rather than the basic matchers provided by RSpec. The Capybara provided matchers include waiting/retrying behavior to handle the asynchronous nature of dealing with the browser. In this case, assuming siteprism_stuff.root_element is the row element then you could be doing something like
expect(siteprism_stuff.root_element).to match_css('.focused-row')
or depending on exactly how your siteprism page objects are setup you could pass the class option to the siteprism existence checker
# `page_section` and `have_row` would need to be replaced with whatever is correct for your site prism page object
expect(page_section).to have_row(class: ['.focused-row'])

Field not showing in TFS 2017 WebLayout

I have enabled the new work item form in TFS 2017 after upgrading from TFS 2015, but have found that there are some fields that aren't showing in the new work item form, even though I can see the field declared in the WebLayout section when editing the work item type XML. Is there a condition which hides fields in WebLayout?
The field I am trying to get appear is the Microsoft.VSTS.Scheduling.RemainingWork field. I have the following inside the WebLayout:
<WebLayout>
<!- Snipped some other groups which show -->
<Group Label="Timescales">
<!-- Snipped Some other fields which show -->
<Control FieldName="Microsoft.VSTS.Scheduling.RemainingWork" Type="FieldControl" Label="Remaining Work" />
</Group>
</WebLayout>
I also had the same issue with a custom String field, but I no longer needed the field so I removed it anyway.
The field is not shown and declared in Web Layout, you need to double check if the field is hidden or have an invalid value of the field.
In your case, you can edit the work item type to add the REQUIRED role from Remaining Work field when change particular States (such as from Done to In Progress). Please follow the below steps:
Open your work item type using TFS Power Tools in (Process Editor).
Under Workflow tab, find the Transition which from Done to
In Progress, then double click on this Transition.
In Workflow Transition dialog, under Fields tab, add the Remaining
Work field, then click OK button and save your work item type.
As a workaround, when you change the statuses, even though the transition was clearing the Reamining Work filed, still need to enter the value for the field.
So, what I found was that when I changed between 2 particular statuses, the transition was clearing the Remaining Work field value. I'm guessing that the WebLayout doesn't display invalid fields, as a blank string is not a valid Double field, which Remaining Work is defined as

Grails : Using select tag of grails with disabled property set to true ignores the value

I need to disable a select element in grails depending on its value. The problem is when I started to add the disable property something is quite wrong with the code.
An example is when the form is sent to the backend, its as if there is no value for that select element and the value sent is null. But, when I checked the DOM, there is a selected attribute in the element. I tried to remove that disabled property because I have a feeling that it has something to do with the bug that I'm encountering and I was right because after removing it, everything worked correctly again.
this is the select tag
<g:select name="detail-entryNameId"
value="${journalEntryName.savingId}"
from="${journalEntryNameInstanceList}"
optionKey="savingId"
optionValue="displayName"
readonly="${journalEntryInstance.paymentMade}"
/>
One more thing about this element is that it can occur as many as possible, which means I have a table and in every row, that element exist so I cannot simply manipulate it.
I've also read in this post how can i make a textfield read only in grails? that "If you use disabled="true" the value will not actually be submitted in the form, so the <g:field/> tag should be used." which proves that disable attribute affects the value of the element.
How can I disable the select element and at the same time, still get its value correctly?
The problem is that in HTML the mere existence of the disabled attribute disables the tag. The value of the attribute (true/false) is ignored.
In such cases the solution is to use an <g:if> to create the tag with or without the disabled attribute according to a condition.
In your case, since you want the value even when the tag is disabled you can add a <g:hiddenField> with the same name and value as the disabled select.

How to make a JIRA Number Field read-only?

As described in the title, I am looking for a smart, safe and efficient way to set a Number Field in JIRA to Read-Only. Below is a short list of approaches, guides and plugins used in an attempt to achieve this.
Installed and deployed the Behaviours Plugin
This resulted in form permission errors all over JIRA setting some of the most basic and editable fields to non-writeable. Further investigation revealed that this is a known issue that will not be fixed anytime soon.
I have gone up and down the options for JIRA's existing Field Behaviour and it simply does not offer the option to set a field to read-only.
Hiding is not an option, as the field needs to be visible (more about that below).
A potential option would be to create a new Screen Scheme that simply excludes this field from the edit screen.
Associating new Screen Schemes with our current project would be a small disaster as many other projects are dependent and shared. Hence making the field read-only or admin-writeable-only would be a much better solution in this instance.
Regarding the Custom Field:
I created a post function in the workflow of our current project that will increase a Custom Number Field by increments of 1 every time an issue/task/bug is reopened. In essence, I am tracking the numbers of reopens. Which brings me to the reason for my read-only requirement. Developers shouldn't be able to change the value of this field as it would throw off statistics.
You can use jquery to make the field read only, add to the field description :
<script type="text/javascript">
AJS.$(document).ready(function() {
AJS.$("#customfield_10000").attr("readonly", true);
});
</script>
change customfield_10000 to your custom field id. You can find this id by viewing the issue edit page source and checking which id does it have.
Check out this and this answers and this for more details.
[UPDATE]
To disable the hover-to-edit function as well, you can add the following script to jira's Announcement Banner , this way it will run on every screen:
<script type="text/javascript">
AJS.$(document).ready(function() {
AJS.$("#customfield_10000").attr("readonly", true);
AJS.$("#customfield_10000").removeClass("editable-field inactive");
AJS.$("#customfield_10000 .icon-edit-sml").remove();
});
</script>
Stopping inline editing from working is trickier it seems. What stopped the Behaviours plugin working for you, do you have a link to the known issue? The one option you haven't listed is to create a new custom field type that extends the familiar Number custom field type but in its velocity template restricts who can edit the field. This kind of customization is documented at https://developer.atlassian.com/display/JIRADEV/Creating+a+Custom+Field+in+JIRA and also in Practical JIRA Plugins (O'Reilly)
Use the "disabled" keyword in your form item. E.g.
Code:
<input type="text" name="foo" value="bar" disabled>

Resources