Getting checkboxes checked in Cypress if id is auto-generated - checkbox

There's a code (not written by me) that contains unique id-s for each checkbox in each table row, which is generated by the system. It looks as below and "12345" is generated automatically for each row added as well as the paths.
The question is, how to specify for testing in cypress, which row I want to check.
The code I'm testing:
<tr class="" xxx-yyy="document-aaa"><td><input id="12345" type="checkbox"><label for="12345"></label></td><td xxx-yyy="document-bbb">word_document.docx</td><td class="text-right"><button class="text-grey-dark" xxx-yyy="delete-document"><svg focusable="false" preserveAspectRatio="xMidYMid meet" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 32 32" aria-hidden="true" class="inline-block" style="will-change: transform;"><path d="Ab13457GHT45"></path><path d="Zxf-67-HJKSx7"></path></svg> delete</button></td></tr>
And the only option I got working in cypress is using "first", but this doesn't allow me to check for example the second one or several checkboxes out of many.
cy.get('[xxx-yyy="document-aaa"]')
.first()
.find('[type="checkbox"]')
.check({ force: true });

You can use eq
cy.get('tbody>tr').eq(0) // Yield first 'tr' in 'tbody'
cy.get('ul>li').eq(4) // Yield fifth 'li' in 'ul'
Good thing to do would be to add within to narrow the area to only that list/table, then find a certain row and check the ckeckbox.

Related

How to dynamically draw edges between nodes using jsplumbtoolkit-react

I'm using jsplumbtoolkit-react 2.x version. Using toolkit.addNode to add new nodes dynamically to the graph. But I'm struggling to draw the connection between the newly added nodes. Can someone please point me to the right documentation or if there is any example that I can follow for this specific version?
I added the following properties on the node component
jtk-port={ctx.data.id}
jtk-scope="varchar"
jtk-source="true"
jtk-target="true"
I do have elementsDraggable: true, so all I'm able to do is drag the node but not form a connection. I tried using addPort but with no luck and the jsPlumbtoolkit documentation has not helped so far.
It's possible you are looking at the 5.x documentation, given that you're using attributes in the above example, although I should note that for users of 5.x the attributes are prefixed with data-, eg data-jtk-source="true" etc. In 2.x this connectivity is not configured with attributes, though, but with elements. For instance, for this demonstration:
https://demo.jsplumbtoolkit.com/react-flowchart-builder/
This is the render method for the action component:
render() {
const obj = this.node.data;
return <div style={{width:obj.w + 'px', height:obj.h + 'px'}} className="flowchart-object flowchart-action">
<div style={{position:'relative'}}>
<svg width={obj.w} height={obj.h}>
<rect x={10} y={10} width={obj.w-20} height={obj.h-20} className="inner"/>
<text textAnchor="middle" x={obj.w/2} y={obj.h/2} dominantBaseline="central">{obj.text}</text>
</svg>
</div>
<div className="node-edit node-action" onClick={this.edit.bind(this)}></div>
<div className="node-delete node-action delete" onClick={this.remove.bind(this)}></div>
<div className="drag-start connect"></div>
<jtk-target port-type="target"/>
<jtk-source port-type="source" filter=".connect"/>
</div>
}
The complete source for the version 2.x code for that demonstration is here:
https://github.com/jsplumb-toolkit-demonstrations/react-flowchart-builder/blob/2.x/src/action-component.jsx

how to show the currently shown entries range in angular

This is what I have used to achieve pagination:
<pagination total-items="reportCount" items-per-page="itemsPerPage" page="currentPage" ng-change="pageChanged()" ng-model="currentPage"></pagination>
How do I get it show the range of entries currently shown.. like.. 1-10 of 46 entries. 11-20 of 46 and so on..
I am able to get it using the value of currentPage and itemsPerPage by doing as follows:
<span id="page_info">Showing {{(currentPage-1) * itemsPerPage + 1}} - {{currentPage * itemsPerPage}} of {{reportCount}} entries</span>
But the issue is in the last page, where the last record is not just currentPage * itemsPerPage, like.. it shows 41-50 of 46 entries.
It should work with {{Math.min((currentPage * itemsPerPage), reportCount)}} but for some reason it isn't evaluating it here.
Any ideas how to get this fixed? or any other way?
Browser Object Model(BOM) will not be directly available when angular bindings are evaluated like Math, console, location, window, etc. You can call them inside a function but not directly on inside binding (Thought there are ways to do that by keep that BOM property on $scope, I'd not recommend to do that). To make it working create a javascript function for inside a $scope and call it on binding level.
<span id="page_info">
Showing {{(currentPage-1) * itemsPerPage + 1}} - {{endCount(currentPage,itemsPerPage, reportCount)}} of {{reportCount}} entries
</span>
Controller
$scope.endCount = function (currentPage, itemsPerPage, reportCount) {
return Math.min((currentPage * itemsPerPage), reportCount);
}

Need to get dynamic count of the selected check-boxes

I'm having the two types of check-boxes one is for selectAll check-box in the data table header, and another type selecting the check-box for each row.
I'm doing a operation, So I need to show the confirmation message, How do I get the count of the selected check-boxes from the Managed Bean.
My code was written in JSF 1.2.
I can able to do select all records, select records, ManagedBean is working fine, But I need to get how many of them got selected for deletion.
Here is the JSF code,
<i:commandLink id="delete"
onclick="if (!confirm('#{managedBean.deleteSelectedCount}')) return false;"
action="#{managedBean.deleteRecords}"
title="Delete records"
immediate="true">
<i:graphicImage url="images/icons/delete.gif" alt="Delete records" />
</i:commandLink>
;
;//Some coding
;
//Data table code starts
<i:dataTable id="caseDataTable"
<h:column>
<f:facet name="header">
<i:selectBooleanCheckbox id="selectAllRecords" title="select All records"
value="#{managedBean.selectAll}">
<a4j:support event="onclick" reRender="caseDataTable,globalMessages" action="#{managedBean.actionSelectAllRecordss}" onsubmit="showBusyIndicator();" oncomplete="hideBusyIndicator();" />
</i:selectBooleanCheckbox>
</f:facet>
<h:outputLabel for="selectCheckbox" value="selectCheckbox"/>
<i:selectBooleanCheckbox id="selectCheckbox"
title="select a record" value="#{managedBean.selected}" >
<a4j:support event="onclick" reRender="selectAllRecords, globalMessages" action="#{managedBean.actionSelectionChange}"
onsubmit="showBusyIndicator();" oncomplete="hideBusyIndicator();"/>
</i:selectBooleanCheckbox>
</h:column>
Possible solution is to use h:inputHidden component (I think it exists in JSF 1.2. If not, you can find some alternative).
For example
Add h:inputHidden to the page
<h:inputHidden id="selectedCountHidden" value="#{managedBean.deleteSelectedCount}"/>
Each time you click on header check box or any of row check boxes, calculate deleteSelectedCount value and re-render h:inputHidden. Something like
<i:selectBooleanCheckbox id="selectCheckbox" title="select a record" value="#{managedBean.selected}" >
<a4j:support event="onclick" reRender="...,selectedCountHidden,..."
And now, since h:inputHidden will always hold deleteSeletedCount value, you can read its value via java script so there is no need for re-loading the page when you click on commandLink
<i:commandLink id="delete"
onclick="if(!confirm(document.getElementById('form:selectedCountHidden').value))return false;"..../>
Note that if you have form with id defined, you will need to call
document.getElementById('form:selectedCountHidden').value
Otherwise just call
document.getElementById('selectedCountHidden').value
In any case, inspect page source and you will find the exact id of p:inputHidden.

Chaining an element using css containing text and accessing an associated field

I need to access the input field in the below html. The way the page is setup I need to chain using the 'Address Line 1' text and then sending text to the input field. The input field id changes and so doesn't the layout of the fields depending on user preference. I am struggling. If you need some more information feel free to ask I did not want to overload with too much information.
<td class="labelCol requiredInput">
<label for="00N36000000xina"><span class="assistiveText">*</span>Address Line 1</label>
</td>
<td class="dataCol col02">
<div class="requiredInput">
<div class="requiredBlock"></div>
<input id="00N36000000xina" maxlength="255" name="00N36000000xina" size="20" tabindex="4" type="text">
</div>
</td>
I have accessed like this:
element(by.css('div.pbSubsection:nth-child(3) > table:nth-child(1) > tbody:nth-child(1) > tr:nth-child(2) > td:nth-child(2) > input'))
However depending on where the user puts the fields it can move around. So what I was hoping was to be able to access the label\ and use that to pinpoint its input field.
I don't know protractor but I cobbled together some code that hopefully will work or be close and I'll give you the thought process and some info and hopefully you can use it to fix my code, if needed, and solve the problem.
Start by finding an element by XPath, "//label[text()='Address Line 1']". This searches for a LABEL tag that contains "Address Line 1". Once you find that element, get the label attribute. From your HTML, this label is the id for the INPUT element you want. Now use the id to find the element and do with it what you want.
id = element(by.xpath("//label[text()='Address Line 1']")).getAttribute("label")
input = element(by.id(id))
input.sendkeys("some text")
Haven't tested this myself, but you could try something like this:
// $ is shorthand for element(by.css())
$('div.assistiveText').getAttribute('for').then(function (val) {
// locate the <input> by the value of the attribute on <label>
element(by.id(val)).sendKeys('abc'); // replace sendKeys with your intended function
});
Or if that first locator on the label isn't specific enough, swap out $('div.assistiveText') for element(by.cssContainingText('Address Line 1'))
I tried it for other attributes (I don't have a for attribute anywhere in my app) and it seemed to work for me.
Try this:
List<WebElement> elementList = driver.findElements(By.cssSelector("tbody > tr"));
for (WebElement element : elementList) {
if(element.findElement(By.cssSelector("td.labelCol > label")).getText().equalsIgnoreCase("Address Line 1")) {
element.findElement(By.cssSelector("input[type='text']")).sendKeys("textToInput");
}
}

Filtering spcific with checkboxes

My question is that I want a filtering system that will filter by checked checkboxes.
The tool is to my comparison website where I compare TV packages.
my visitors should filter the packages by the tv-channels they want to se.
example;
Checkbox 1: Discovery
Checkbox 2: Animal PLanet
Checkbox 3: Disney Channel
Output should be the matching TV-package
Package 1: (contains Discovery and Disney channel)
Package 2: (contains Animal Planet, Disney channel)
Package 3: (contains Animal Planet)
So if checkbox 1 is checked it should only show package 1.
if checkbox 1 + checkbox 2 is checked it should say "No match found, but this package was was closest to your choice"
if checkbox 2 + checkbox 3 is checked it should only show package 2 which match the visitors choice exactly.
I hope your can help me out. I have been searching a lot after this specific solution without any success.
I think it should be in Jquery. i have seen some simular filtering examples, but no one there are like my wish above.
This is an old question, but... I'll take a shot. Working jsfiddle: http://jsfiddle.net/a0nnrfua/
I think a lot really depends on how you intend to define "closest", but presuming a jQuery solution and hopefully your browser requirements aren't TOO far in the past, you could use the data- attributes and jQuery to come up with some relatively simple functions. Or even use the value portions of the checkboxes really.
Psuedocode, it would look like:
Define a click or change handler to detect whenever a checkbox has been touched/changed.
Define a function that will scan all checked items and pass the values into your "closest package" function.
Based on the results of that function, filter your package selection so that your choices are highlighted or marked in some way.
So let's presume the following HTML markup:
<h3>TV Channels</h3>
<div id="TVChannelSelections">
<input type="checkbox" class="tvchannel" name="tvchannel" id="tvchannel_Discovery" value="Discovery" />
<label for="tvchannel_Discovery">Discovery Channel</label>
<br/>
<input type="checkbox" class="tvchannel" name="tvchannel" id="tvchannel_AnimalPlanet" value="Animal Planet" />
<label for="tvchannel_AnimalPlanet">Animal Planet</label>
<br/>
<input type="checkbox" class="tvchannel" name="tvchannel" id="tvchannel_DisneyChannel" value="Disney Channel" />
<label for="tvchannel_Disney">Disney Channel</label>
<br/>
</div>
<div id="message"></div>
<h3>Packages</h3>
<div id="FilteredPackages">
<div class="package deselected" id="Package1" data-channels="Discovery,Disney Channel">Package #1</div>
<div class="package deselected" id="Package2" data-channels="Animal Planet,Disney Channel">Package #2</div>
<div class="package deselected" id="Package3" data-channels="Animal Planet">Package #3</div>
</div>
So in jQuery, your generic change or click handler would be defined in code: Note that I'm saying, any element on your page that has the class "tvchannel" defined, if there's ever a change that occurs, run my filter function.
<script type="text/javascript" src="../path/to/jQuery/library"></script>
<script type="text/javascript">
$(document).ready(function() {
$(".tvchannel").on("change", function() {
FilterMySelectedChannels();
});
});
</script>
Now we can define your Filter function. We're going to assume two things. #1, that we want to find all the selected checkboxes and their values. Then we're going to iterate through the data-channels property of all of our packages (defined as elements with class = "package"). We'll use some form of string comparison and boolean logic to define what a complete match is vs. a close but no cigar match vs. a complete fail.
In order to keep track of things I'm using 3 classes, selected, deselected, and close.
In css, you can decide whether you want notselected to mean "hide the package completely" (i.e. display: none;) or maybe you want it to be visible but greyed out and "struck out" (i.e. text-decoration: strikethrough; color: grey;}
I'm going to use kind of a brute force way of doing the comparison. There are better array functions and comparison functions in javascript, but this should be relatively clear for most people and I trust the good folks at stackoverflow to chime in with better solutions. But this should get you started. :)
<script type="text/javascript">
function FilterMySelectedChannels() {
$checkedboxes = $(".tvchannel:checked");
$packages = $(".package");
var bAnyFound = false;
$packages.each(function () {
var bCloseButNoCigar = false;
var bCompleteMatch = true;
var packagearray = $(this).data("channels").split(",");
var $currentPackage = $(this);
$checkedboxes.each(function () {
if ($.inArray($(this).val(), packagearray) != -1) {
bCloseButNoCigar = true;
} else {
bCompleteMatch = false;
}
});
if (bCompleteMatch) {
$currentPackage.removeClass("selected").removeClass("deselected").removeClass("close").addClass("selected");
bAnyFound = true;
} else if (bCloseButNoCigar) {
$currentPackage.removeClass("selected").removeClass("deselected").removeClass("close").addClass("close");
} else {
$currentPackage.removeClass("selected").removeClass("deselected").removeClass("close").addClass("deselected");
}
});
if (bAnyFound) {
$("#message").html("The following matches were found");
} else {
$("#message").html("No actual matches were found, but here are some close matches based on your selections");
$(".package.close").removeClass("deselected").removeClass("close").removeClass("selected").addClass("selected");
}
}
</script>
<style type="text/css">
.selected {
color: red;
background-color: yellow !important;
}
.deselected {
color: grey;
text-decoration: strike-through !important;
background-color: white !important;
}
</style>
There are obvious optimizations that could probably work here, but it's a start for those trying to do something similar. Note that it assumes that your markup is dynamically generated or properly coded. If you need to guard against human typos, converting your text using .toLowerCase/UpperCase and using the .Trim functions to eliminate extra space will assist. But you still have to choose your data values wisely so there's no overlap. And if you choose them well enough you can use better techniques such as regular expressions and wildcard searches to make the code a bit shorter.
Hope this helps someone!

Resources