Cypress test conditional check based on attributes - cypress

I am trying to do a conditional check based on attribute [data-x="transit"].
In few HTML page[data-x="transit"] contains within li and other case within div.
example:
<ul>
<li data-x="transit">ele</li>
<ul>
<div>
<div data-x="transit"> ele</div>
</div>
how can I write a cypress conditional test to check
if data-x="transit" with li exist:
execute li commands
else if data-x="transit" with div exist:
execute div commands

You can tell which element type from the tagName property.
cy.get('[data-x="transit"]')
.then($el => {
if ($el[0].tagName === 'LI') { // always check upper-case
...
}
if ($el[0].tagName === 'DIV') {
...
}
})

Related

nightwatch select current element's inner div

i'm new to nightwatch and was wondering if there's any good way to select the inner element of a current element and then get the text? Assuming i have the following..and i'm trying to retrieve the text inside (a) tags of each (li).
so i would like to get 'text to retrieve' and 'text to retrieve 2'.
...
<div class="mywrapperhere">
<ul>
<li>
<a>.....
<div>text to retrieve</div>
</a>
</li>
<li>
<a>.....
<div>text to retrieve 2</div>
</a>
</li>
<li>...
...
</div>
I'm thinking along these lines..
module.exports = {
'Demo test 1' : function (browser) {
....
//some sort of selector then gets from the anchor list
...'.mywrapperhere li a') : {
..
//for each element of the anchor..
{
//is there anyway to get it through something like
element.('div').innerHTML eg..
//or am i forced to use browser.execute( ...getElementsByTag method
//to achieve this?
}
}
browser.end();
}
};
Looking at the nightwatch api, i couldn't find anything allows me to do that. I'm particularly looking at the 'Element State' examples that doesn't seem to have a way for me to select the current element state's child element :
http://nightwatchjs.org/api/elementIdAttribute.html
The reason why i had to loop through the anchor tag level is because i'll need to retrieve a few more data besides the one from div tag, thanks!
You can use elementIdElement and elementIdText to get text from a child element. First you can get all the li elements by using .elements(). Then you use elementIdElement to get a child element. Then you can use elementIdText to get the text of this child element. Here is an example that will allow you to get the text of both list items in your snippet and log the values to the console.
browser.elements('css selector', 'li', function(listItems) {
listItems.value.forEach(function(listItem) {
browser.elementIdElement(listItem.ELEMENT, 'css selector', 'a', function(anchor) {
browser.elementIdText(anchor.ELEMENT, function(text) {
console.log(text.value);
});
});
}, browser); //have to pass in browser for scoping
});

Selenium not grabbing the selected element but the one loaded by Javascript

I am using selenium to grab the href attribute of the a tag. But my code is not grabing the "/pros/52698281" as it should.
Is it because my code is wrong or because some javascript is loading dynamically another url ? Could he ?
Here is the html :
<article class="bi-bloc blocs clearfix bi-pro visited" id="bi-bloc-014805042600000000C0001" data-pjtoggleclasshisto="{"idbloc": {"id_bloc": "014805042600000000C0001", "no_sequence": "" }, "klass":"visited" }">
<div class="zone-bi">
<a class="visible-phone mob-zone-pro pj-lb pj-link" data-pjsearchctx-sethref="" href="/pros/52698281" data-pjstats="{"idTag":"MOB-ZONE-PRO","pos":54,"type_bi":"pro","genreBloc":"1","pjscript":"xt_click({},'C','{%xtn2}','LR_BI::zone_identification::info{%pjstats.type_bi}::identification_pro','A');"}">
<span class="not-visible">
XXXXXXXXXXX
</span>
</a>
I am using this code to grab the href attribute.:
elements = driver.find_elements(:css, "article.bi-bloc div.zone-bi a.visible-phone")
elements.each do |e|
p e.attribute("href")
end
Here is the javascript code that, I think, loads dynamically another url (the one printing in my terminal).
<script type="text/javascript">
var pj_searchctx = {
"1989516432": {
"form": {
"quoiqui": "climatisation",
"ou": "paris-75",
"proximite": 0
},
"search": {
"technicalUrl":"/annuaire/chercherlespros?quoiqui=climatisation&ou=paris-75&idOu=L07505600&page=3&contexte=BupKFuSlIjbFtxi68rty83eKL16bkxx3e0d5jKAkSaA%3D&proximite=0&quoiQuiInterprete=climatisation",
"breadcrumb": "Retour aux résultats",
"stats": {
"idTag": "VERS-LR-RESULTATS"
}
}
}
};
Any idea how I can do ?
Since you're using direct children in your CSS selector, try using this instead of yours (with >):
"article.bi-bloc > div.zone-bi > a.visible-phone"
This matches more specifically the element your looking for.

Rivetsjs iteration - by using an integer instead of collection

According to rivetsjs docs, we can render content by iterating over a object (array) by,
<ul>
<li rv-each-todo="list.todos">
<input type="checkbox" rv-checked="todo.done">
<span>{ todo.summary }</span>
</li>
<ul>
but is there a way where I can iterate by using a single integer to indicate number of times the iteration to take place?
I mean something like this,
<li rv-each="list.num_of_todos">
...
where num_of_todos is an integer to indicate number of iterations to take place.
There is no "proper" way of doing it. However, you can easily mimic this using a formatter that returns an array as shown below:
var list = {
name: 'to do list',
noOfToDos: 5
};
rivets.formatters.makearray = function(value) {
var result = [];
while (value--) {
result.push(0)
};
return result;
}
rivets.bind($("ul"), { // bind rivets
list: list
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/rivets/0.7.1/rivets.bundled.min.js"></script>
<ul>
<li rv-each-item="list.noOfToDos | makearray">Test</li>
<ul>

Autoclosing unclosed tags in template

Hi i'm tring to create such template
<script type='text/mustache' id='user-template'>
<ul>
{{#each users}}
<li>{{name}}</li>
{{#startHidden #index 2}}</ul><ul style = "display:none;">{{/startHidden}}
{{#endHidden #index 2}}</ul>show all{{/endHidden}}
{{/each}}
</ul>
</script>
So the idea is to close the upper <ul> after second user in list open new hidden <ul> and put all rest users here. But instead i got closed <ul> and final html looks like:
<ul>
<li>name1</li>
<li>name2</li>
<ul style="display:none;"></ul>
<li>name3</li>
<li>name4</li>
show all
</ul>
This is my js
var data = [{name: "name1"},{name: "name2"},{name: "name3"},{name: "name4"}];
var users = new can.List(data);
var frag = can.view("user-template",{users:users},{
'startHidden' : function(currentIndex, usersToShow, options){
if (currentIndex() === usersToShow-1) {
return options.fn(this);
}
},
'endHidden' : function(currentIndex, usersToShow, options){
var length = options.scope.attr('users').length;
if ((length>usersToShow)&&(currentIndex() === length-1)) {
return options.fn(this);
}
}
});
Is there any way to prevent auto closing tags, or may i'm just doing it wrong completely?
This is not possible. can.view.live.html can only remove or add elements in sequence. A workaround would be to just add a "hidden" class on an LI if it shouldn't be visible.

How to perform click event on an element present in the anchor tag?

<div class="buttonClear_bottomRight">
<div class="buttonBlueOnWhite">
<a onclick="$find('{0}').close(true); callPostBackFromAlert();" href="#">Ok</a><div
class='rightImg'>
</div>
</div>
</div>
In the above code i wanted to click on Ok button present in the anchor tag.But an id is not generated because of which i cannot directly perform a click action. I tried a work around mentioned below.
IElementContainer elm_container = (IElementContainer)pw.Element(Find.ByClass(classname));
foreach (Element element in elm_container.Elements)
{
if (element.TagName.ToString().ToUpper() == "A")
{
element.Click();
}
}
But here elm_container returns null for intial instances due to which we cannot traverse through it. Is there any other easy method to do it ?
Try this...
Div div = browser.Div(Find.ByClass("buttonClear_bottomRight")).Div(Find.ByClass("buttonBlueOnWhite"));
Debug.Assert(div.Exists);
Link link = div.Link(lnk => lnk.GetAttributeValue("onclick").ToLower().Contains(".close(true)"));
Debug.Assert(link.Exists);
link.Click();
Hope it helps!
You can simply Click on the link by finding its text
var OkButton = Browser.Link(Find.ByText("Ok"));
if(!OkButton.Exists)
{
\\Log error here
}
OkButton.Click();
Browser.WaitForCompplete();
Or you can find the div containing the link like,
var ContainerDiv = Browser.Div(Find.ByClass("buttonBlueOnWhite"));
if(!ContainerDiv.Exists)
{
\\Log error here
}
ContainerDiv.Links.First().Click();
Browser.WaitForComplete();

Resources