How to use protractor to test class existance - jasmine

I am using protractor to test my site. I countered a problem.
I have a ul, the number of li inside is dynamic,
<ul>
<li class='listing-item'>
<div class='prod-price'>$99</div>
</li>
<li class='listing-item price-onsale'>
<div class='prod-price'>$99</div>
<div class='prod-saving'>$10</div>
</li>
<li class='listing-item'>
<div class='prod-price'>$50</div>
</li>
...
</ul>
The 'prod-saving' div will only show up when 'price-onsale' class is present. I want to use protractor to test this logic, is there a way to do it? something like:
expect(elment(by.className('price-onsale').isPresent()).toBe(true).when('price-onsale).isPresent();

Your syntax will work almost word-for-word if you rearrange it a bit:
element(by.className('price-onsale')).isPresent().then(function(present) {
if(present) {
expect(element(by.className('prod-saving')).isPresent()).toBe(true);
}
});
It's a matter of testing the pre-condition first, and then testing the main condition based on the result of the first.

Related

Cypress: How to get <li> only without its children <li>?

I'm recently using cypress and I want to get the array of list but I just want the to get <li> under the class "list" and not including the other children of <li>
I'm using
cy.get('.list >li')
but I'm also getting the children <li> under Home.
<ul class="list">
<li>Home</li>
<ul>
<li>Another One</li>
<li>Another Two</li>
</ul>
<li>Page</li>
<li>Hello</li>
<li>Hi</li>
</ul>
you have two ways to do this
get only li children of parent
cy.get('.list').children('li')
get children by level in dom
cy.get('.list > li')
.its('length')
.should('eq', 2)
You can also use the combination of selector and text using contains. In this way you will only get the intended li element.
cy.contains('li', 'Home')
You can do something like this as well:
cy.get('ul.list > li').each(($ele) => {
cy.log($ele.text()) //prints Home Page Hello Hi
})
Created a small POC from your HTML and this is what I got:

Select visible xpath in list

I am trying to get the error message off of a page from a site. The list contains several possible errors so i can't check by id; but I do know that the one with display:list-item is the one I want. This is my rule but doesn't seem to work, what is wrong with it? What I want returned is the error text in the element.
//*[#id='errors']/ul/li[contains(#style,'display:list-item')]
Example dom elements:
<div id="errors" class="some class" style="display: block;">
<div class="some other class"></div>
<div class="some other class 2">
<span class="displayError">Please correct the errors listed in red below:</span>
<ul>
<li style="display:none;" id="invalidId">Enter a valid id</li>
<li style="display:list-item;" id="genericError">Something bad happened</li>
<li style="display:none;" id="somethingBlah" ............ </li>
....
</ul>
</div>
The correct XPath should be:
//*[#id='errors']//ul/li[contains(#style,'display:list-item')]
After //*[#id='errors'] you need an extra /, because <ul> is not directly beneath it. Using // again scans all underlying elements for <ul>.
If you are capable to not use // it would be better and faster and less consuming.

using variables in HtmlXPathSelectors

I am using Scrapy and have run into a few places where it would be nice to use variables, but I can't figure out how. Meaning if I have some long string it would be nice to store it in a variable long_string and then select for it: hxs.select('\\div[#id=long_string]').
I'm sure this is supported by Scrapy and I just can't figure it out as it wouldn't make sense for you to always have to hard-code the string in.
Update:
So for the sample text below I want to extract the div where id="footer":
<div id="footer">
<div id="footer-menu">
<div class="region-footer-menu">
<div id="block-menu-menu-footer-menu" class="block-menu">
<div class="content">
<ul class="menu">
<li class="first leaf">FAQs</li>
<li class="leaf">Media</li>
<li class="leaf">Partners</li>
<li class="last leaf active-trail">Jobs</li>
</ul>
</div>
</div>
<div id="block-block-52" class="block block-block">
<div class="content">
<p>SUPPORT</p>
</div>
</div>
</div>
</div>
</div>
We initialize hxs = HtmlXPathSelector(response) for all the below segments.
The following code selects only the first div:
hxs.select('//div[#id=concat("foot","er")]')
This code selects nothing but gives no error:
hxs.select('//div[#id="foot"+"er"]')
Both of the below code segments select nothing and give no errors:
long_string = "foot"
hxs.select('//div[#id=concat(long_string,"er")]')
hxs.select('//div[#id=long_string]')
I would like to be able to do either of the bottom two methods and return the desired results.
Assuming + works for string concatenation in Scrapy, this should work:
hxs.select('//div[#id="' + long_string + '"]')
I'm not familiar with Scrapy, but I don't think you'll be able to select a div that doesn't exist.
have you tried?
hxs.select('\\div[#id="' + long_string_variable + '"]')

How do I make a AJAX nested list, in AngularJS?

I've made a list who's content is loaded via AJAX, and it works as intended.
I'd now like to make each list entry load (via AJAX) and display a sublist, when clicked upon.
Is this possible in AngularJS? (I'm new to AngularJs and am more than a little confused over $scope.)
<div ng-controller="StockGroupCtrl">
<ul>
<li ng-repeat="group in groups">
<span>{{group.prod_grp}}</span>
<span>{{group.desc}}</span>
<!-- something like
<ul ng-controller="WhatShouldItBe?">
<li ng-repeat="item in items">
<span>{{item.name}}</span>
<span>{{item.price}}</span>
</li>
</ul>
-->
</li>
</li>
</div>
I've made the outer code work with:
function StockGroupCtrl($scope, $http) {
$scope.groups = [];
$scope.handleGroupsLoaded = function(data, status) {
$scope.groups = data;
}
$scope.fetch = function() {
$http.get('/api/stock/groups/').success($scope.handleGroupsLoaded);
}
$scope.fetch();
}
but I can't really see where to start with the inner lists.
How about this? You don't need another controller.
<ul>
<li ng-repeat="item in group.items">
<span>{{item.name}}</span>
<span>{{item.price}}</span>
</li>
</ul>

Using hoverintent, instead of show/hide...help using changing code please

I know there are many great helpers on this site, I am still learning jquery, but I love the functionality behind it. Recently I created a megadrop down menu, but I started getting a lot of recommendations to use the hoverintent plugin instead of using show/hide. I am lost trying to change my coding around to get it to work...PLEASE HELP...THANKS AS ALWAYS GUYS AND GALS!!!
OH and I think that changing to hoverintent will stop the overflows from building up too, but I do not think my code is working to stop that from happening?
My site...only the About DKE dropdown works...
http://www.nestudiosonline.com/test.php
my jquery script...
$(document).ready(function() {
// shows the hidden div in the list
$('#dave').mouseover(function() {
$('#aboutdke').show('slow');
});
// hides the hide the div again for that list item
$('#dave').mouseleave(function() {
$('#aboutdke').hide('slow');
});
});
Here is my html....
<div id="pagelinks">
<ul id="menu">
<li class="mega"><a class="dkeorg" href="#">DKE.ORG</a></li>
<li class="megamenu" id="dave"><a class="links" href="#">ABOUT DKE</a><div id="aboutdke">
(about dke div content)
</div>
</div></li>
<li class="megamenu"><a class="links" href="#">ALUMNI</a></li>
<li class="megamenu"><a class="links" href="#">UNDERGRADUATES</a></li>
<li class="megamenu"><a class="links" href="#">EVENTS</a></li>
<li class="megamenu"><a class="links" href="#">MULTIMEDIA</a></li>
<li class="megamenu"><a class="links" href="#">SHOP DKE</a></li>
</ul>
</div>
Two things before I get to the real answer:
You're missing the opening body tag after your doctype.
Only lowercase tags are valid in XHTML.
The events are only triggered for #aboutdke because that's the one element you have hardcoded into the event callback functions. Try something more abstract:
$('#menu > li').mouseover(function() {
$(this).children().is('div').show('slow');
});
$('#menu > li').mouseleave(function() {
$(this).children().is('div').hide('slow');
});
This should (if memory serves) work for every menu item.

Resources