How to use result of .length in selector Cypress - jquery-selectors

I'm trying to perform an action based on the results of an earlier assertion. I have the following situation, I want to determine the number of versions for a document, this is represented in the follwing html:
<ul data-testhook-id="accordion-body">
<li data-testhook-id="accordion-body-item">
<div>
<div data-testhook-id="version-1">
<div data-testhook-id="avatar">
<div data-id="tooltip">John Doe</div>
</div>
</div>
<span data-testhook-id="content">1. 17-08-2018 at 15:26</span>
</div>
<div data-testhook-id="version-2">
<div data-testhook-id="avatar">
<div data-id="tooltip">John Doe</div>
</div>
</div>
<span data-testhook-id="content">2. 20-08-2018 at 13:05</span>
</div>
<div data-testhook-id="version-3">
<div data-testhook-id="avatar">
<div data-id="tooltip">Jane Doe</div>
</div>
</div>
<span data-testhook-id="content">3. 20-08-2018 at 13:11</span>
</div>
<div data-testhook-id="version-4">
<div data-testhook-id="avatar">
<div data-id="tooltip">No Body</div>
</div>
</div>
<span data-testhook-id="content">4. 21-08-2018 at 13:11</span>
</div>
<svg width="12" height="12" data-testhook-id="icon-active-version"><path d="path-here"></path></svg>
</div>
</div>
</li>
Each element with test id data-testhook-id="version-xxx" is a line containing version information and its these div elements I want to count. for this I have set up the following:
cy.get('[data-testhook-id="accordion-body-item"] > div > div').its('length').as('versions')
Now if I add the following assertion, this passes without any problem
cy.get('#versions').should('equal', 4)
But if I try to use the outcome of the number of div's found as a variable in a console.log I no longer get '4' but [object, Object]. Tried this by:
var size = cy.get('[data-testhook-id="asset-versions"] [data-testhook-id="accordion-body-item"] > div > div').its('length')
console.log('foo ' + size)
Which results in foo [object Object] being printed to the console.
What I want to do is use the number of items in a selector to select an element, like:
cy.get('[data-testhook-id="accordion-body-item"] > div > div:nth-child(' + size + ')').find('svg').should('have.attr', 'data-testhook-id', 'icon-active-version')
But as the var is not a number I get the msg
Error: Syntax error, unrecognized expression: :nth-child
[data-testhook-id="asset-versions"] [data-testhook-id="accordion-body-item"] > div > div:nth-child([object Object])
Is it possible to use the number of elements found as a variable for a next selector?

Try this:
cy.get('[data-testhook-id="accordion-body-item"] > div > div').its('length').then((size) => {
cy.get('[data-testhook-id="accordion-body-item"] > div > div:nth-child(' + size + ')').find('svg').should('have.attr', 'data-testhook-id', 'icon-active-version')
});
You cannot assign or work with the return values of any Cypress command. Commands are enqueued and run asynchronously. What commands really return are Chainable<typeOfValueYouWant>, in another words, it's kind of queue object which resolves with desired value.
Read more here
BTW: I think you should consider change your approach for selecting elements. Read more here.
For those who are using Typescript - I wrote plugin for tslint which prevents making this mistake: https://github.com/krzysztof-grzybek/tslint-plugin-cypress

Related

Show Hide HTML Attribute in AEM

Let's pretend I have a boolean paratemeter called isDisabled. If isDisabled is true, we want to add a custom html attribute called data-enable-hide; otherwise, we will not show the html attribute.
The option I could think of is:
<div data-sly-test="${model.isDisabled}">
<div class="container" data-enable-hide>
Hello World
</div>
</div>
<div data-sly-test="${!model.isDisabled}">
<div class="container">
Hello World
</div>
</div>
This option would work but it would duplicate the inner HTML because the only difference is to show and hide the HTML attribute. Is there any specific syntax from AEM that would allow me to show/hide HTML attribute based on boolean condition?
You can make use of test conditions directly within the attribute as shown below
<div class="container" data-enable-hide="${isDisabled || ''}">
Hello World
</div>
This would output <div class="container" data-enable-hide="true"> if isDisabled is true or it will remove the whole attribute if it is false i.e., the output would be <div class="container"> when false
data-sly-test="${!model.isDisabled}"
What syntax is this?
Use an IF condition if possible:
#if(isDisabled)
{
<div class="container" data-enable-hide>
Hello World
</div>
}

AEM HTL repeating an element containing "data-sly-resource" using data-sly-repeat

I am trying to loop through an div element containing "data-sly-resource" to be able to include that component as a child.
I have a table element where each cell has an individual authoring interface using a child component. I get two counts that is rowCount as array of "x" and columnCount as array of "y". I'm able to iterate through the class="table-cell" and am able to add "y" number of columns with their respective child components using data-sly-resource . But when I'm trying to iterate through class="table-row" using rowcount it only iterates the content and adds "y" number of rows but doesn't add child components in the rows
thank you
<div class="table">
<sly data-sly-list.card="${rowCount.array}">
<div class="table-row">
<sly data-sly-list.card="${columnCount.array}">
<div class="table-cell" data-sly-test.resourceNode="${['cell', card.intValue] #join='-'}">
<div data-sly-resource="${ #path=resourceNode,
resourceType='example/components/content/tableLongForm/rte'}"
data-sly-unwrap="${!wcmmode.edit && !wcmmode.preview}" style="width:60px;"></div>
</div>
</sly>
</div>
</sly>
</div>
Authoring Interface Image
You are using the same identifier card for the list items in the nested loops, perhaps you meant it as:
<div class="table">
<sly data-sly-list.row="${rowCount.array}">
<div class="table-row">
<sly data-sly-list.card="${columnCount.array}">
<div class="table-cell" data-sly-test.resourceNode="${['cell', row.intValue, card.intValue] # join='-'}">
<div data-sly-resource="${ #path=resourceNode,
resourceType='example/components/content/tableLongForm/rte'}"
data-sly-unwrap="${!wcmmode.edit && !wcmmode.preview}" style="width:60px;"></div>
</div>
</sly>
</div>
</sly>
</div>

Skip a loop in alpine.js with x-if

I use this loop
<form action="/" method="POST">
<template x-for="(deck, index) in $store.cart.decks">
<div x-show="$store.cart.total(index) > 0">
<div><span x-text="$store.cart.total(index)"></span> Karten</div>
<div x-text="deck.price"></div> €
<input :name="'deck[' + index + '][name]'" :value="$store.cart.decks[index].name">
</div>
</template>
</form>
Which works fine and displays all items in my cart and hides those that have a total of 0.
But this will only set the item with 0 on display:none, which will still transfer the data in the POST request.
I tried to use x-if instead of x-show but that is only allowed on a tempate tag.
I tried to add the x-if on the template tag:
<template x-show="$store.cart.total(index) > 0" ...
this results in an error, because index is not set at that point
I tried to add another <template> tag inside the existing template, but then the variables index and deck are not available inside the second any more
How do I prevent the zero cart items being computed in my POST request?
I think something like the following would work, note the div inside both template elements.
<template x-for="(deck, index) in $store.cart.decks">
<div>
<template x-if="$store.cart.total(index)">
<div>
<!-- rest of the content -->
</div>
</template>
</div>
</template>

Jquery selector seems not to work in google chrome

I want to update the value from a input/textfield with a calculated value from the cookie.It's like a mini local cookie cart.
Saving and retrieving the json from the cookie is a piece of cake.
In my behavior I fail to make the following work:
I added a class for every node in the input field, it's constructed like the example below.
Myid = 'webform_cart_nid_10';
formElement = $('.' + Myid);
console.log(formElement);
The html is quite nested and can be seen http://it2servu.be/broodjes/bestellen (if I may link?) .
the field whose value I want to update looks like this:
<input class="webform_cart_nid_10 webform_cart_nid form-text" type="text" id="edit-submitted-cart-item-cart-elements-10" name="submitted[cart_item][cart_elements][10]" value="0" size="3" maxlength="128">
Is contained in drupal output with severe div-itis.
<div class="page clearfix" id="page">
<div id="section-content" class="section section-content">
<div id="zone-content-wrapper" class="zone-wrapper zone-content-wrapper clearfix">
<div id="zone-content" class="zone zone-content clearfix container-12">
<div class="grid-12 region region-content" id="region-content">
<div class="region-inner region-content-inner">
<div class="block-inner clearfix">
<div class="content clearfix">
<div class="node node-webform node-promoted view-mode-full clearfix ">
<div class="field field-name-title field-type-ds field-label-hidden">
<form class="webform-client-form" enctype="multipart/form-data" action="/broodjes/bestellen" method="post" id="webform-client-form-5" accept-charset="UTF-8">
<div>
<fieldset class="collapsible form-wrapper collapse-processed" id="edit-submitted-cart-item-cart-elements">
<div class="fieldset-wrapper">
<div class="form-item form-type-textfield form-item-submitted-cart-item-cart-elements-10">
<input class="webform_cart_nid_10 webform_cart_nid form-text" type="text" id="edit-submitted-cart-item-cart-elements-10" name="submitted[cart_item][cart_elements][10]" value="0" size="3" maxlength="128">
...
probably it's something stupid, I just can't figure out what it is?
Your problem is with jQuery. If you pop open the console in Chrome and type jQuery, it returns the jQuery function. If you type $ it returns undefined. You have some sort of collision causing $ not to be set to jQuery.
use "jQuery" instead of "$"
Myid = 'webform_cart_nid_10';
formElement = jQuery('.' + Myid);
console.log(formElement);
the "$" never worked for me in Drupal 7.

How to get the index of the ACTIVE CHILD div of my container with jQuery?

<div id="container">
<div class="active">
<div class="active"></div>
</div>
<div>
</div>
</div>
How to write such a container?
Use .index() without parameters to get it's (0-based) index amongst siblings, like this:
var index = $("#container .active").index();
You can test it out here. For your example markup, it would be 0.