I need to write automation tests in Cypress for carousel with images.
I have something like this:
<div id="carouselExampleControls" class="carousel slide" data-ride="carousel">
<div class="carousel-inner">
<div class="carousel-item active">
<img class="d-block w-100" src="..." alt="First slide">
</div>
<div class="carousel-item">
<img class="d-block w-100" src="..." alt="Second slide">
</div>
<div class="carousel-item">
<img class="d-block w-100" src="..." alt="Third slide">
</div>
</div>
<a class="carousel-control-prev" href="#carouselExampleControls" role="button" data-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
<a class="carousel-control-next" href="#carouselExampleControls" role="button" data-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div>
The carousel change automatically. The active image gets class "slider_wrapper__activeSlide__2LNke", and the other image has class "slider_wrapper__nextSlide__1Vnk4". I would like to check whether the carousel is displayed on the page and whether the active image has the correct class.
I try with .should ('include') but it does not work :(
You can use .find() to query for elements underneath a yielded element.
cy.get('.carousel-item.active') // get the active div
.find('img') // get the img element underneath the above div
.should('be.visible') // check that the element is visible
.and('have.class', 'slider_wrapper__activeSlide__2LNke'); // check for the active image class.
If you need to check each of the carousel items, you'll have to use JQuery's hasClass.
cy.get('.carousel-item') // retrieve all elements with carousel-item class
.each(($item) => { // iterate through all elements
cy.wrap($item) // wrap the yielded element
.find('img') // find the img
.should('have.class', $item.hasClass('active') ? 'slider_wrapper__activeSlide__2LNke' : 'slider_wrapper__nextSlide__1Vnk4');
// ^ ternary to determine which class we are checking for
The carousel change automatically. To test that aspect, use cy.clock() to "freeze" the movement, then cy.tick(3000) to slide to next image (assuming 3 second delay).
cy.clock()
cy.get('div#carouselExampleControls')
.find('div.carousel-item.active')
.invoke('index')
.should('eq', 0) // first image is active
cy.tick(3000)
cy.get('div#carouselExampleControls')
.find('div.carousel-item.active')
.invoke('index')
.should('eq', 1) // second image is active
Try not to use classes with suffixes like __2LNke, they could be generated by the framework and change on next build.
If you want to check then, use the prefix part slider_wrapper__activeSlide and slider_wrapper__nextSlide
cy.get('[class*="slider_wrapper__nextSlide"]') // partial matching, more robust
Related
Does anyone know how to override the default bootstrap carousel functionality of keyboard left and right buttons working only after first clicking one of the arrows on the screen.
I have rows of cards which when clicked opens a modal and inside that modal I have my carousel. I'd like the user to immediately be able to use the keyboard arrows and not have to click the arrows on the screen to enable the keyboard arrows to work. This appears to be the default behavior.
I've tried using $(#exampleId).focus() on various elements in the modal and carousel but no luck getting it to work thus far.
The default behavior can be seen in the bootstrap carousel doc:
https://getbootstrap.com/docs/5.0/components/carousel/#with-controls
Bootstrap-5 Carousel with controls code:
<div id="carouselExampleControls" class="carousel slide" data-bs-ride="carousel">
<div class="carousel-inner">
<div class="carousel-item active">
<img src="..." class="d-block w-100" alt="...">
</div>
<div class="carousel-item">
<img src="..." class="d-block w-100" alt="...">
</div>
<div class="carousel-item">
<img src="..." class="d-block w-100" alt="...">
</div>
</div>
<button class="carousel-control-prev" type="button" data-bs-target="#carouselExampleControls" data-bs-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="visually-hidden">Previous</span>
</button>
<button class="carousel-control-next" type="button" data-bs-target="#carouselExampleControls" data-bs-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="visually-hidden">Next</span>
</button>
</div>
Edit:
After following bootstrap documentation link you'll see that you can only slide the carousel using the keyboard after clicking one of the controls on the carousel "<" or ">". If you just start by using your left or right arrow keyboard buttons the carousel doesn't respond.
I have a website coded with standard stuff (html, javascript, jquery, php). I have a folder that I will dump images into throughout the day. I need to be able to access the website on a tablet, swipe from image to image and be able to select one or more (by filename) and then pass that list to the next procedure.
I do primarily database forms and such, not sure about the displaying of images and the swiping and keeping track of the selected images. Any help to point me in the right direction would be appreciated! I don't really expect anyone to do my work...just not sure where to start (yes, I've been Googling for a while).
Thanks!
There's many different possibilities in solving your issue. You can use Bootstrap's Carousel. It works fairly well; and assuming you're using PHP, you can create elements based on the directory content.
Your base code for the Carousel - straight from Bootstrap's content:
<div id="carouselExampleControls" class="carousel slide" data-ride="carousel">
<div class="carousel-inner">
<div class="carousel-item active">
<img class="d-block w-100" src="..." alt="First slide">
</div>
<div class="carousel-item">
<img class="d-block w-100" src="..." alt="Second slide">
</div>
<div class="carousel-item">
<img class="d-block w-100" src="..." alt="Third slide">
</div>
</div>
<a class="carousel-control-prev" href="#carouselExampleControls" role="button" data-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
<a class="carousel-control-next" href="#carouselExampleControls" role="button" data-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div>
To make a automated PHP script you could use scandir and use a foreach loop to loop through the content:
<?php
$dir = './images/';
$file_list = array_diff(scandir($dir), array('..', '.'));
foreach($file_list as $item)
{
echo '<div class="carousel-item">';
echo '<img="' . $item . '" class="d-block w-100">';
echo '</div>';
}
?>
That will create a loop based on the files in that directory.
Website: http://freedomcreativesolutions.com/old/steamsource/
Problem: Trying to implement the javascript slide.bs.carousel into the code so that the caption delays and comes in a few seconds after the picture loads in the slideshow. I placed the code for 'slide.bs.carousel' in a script tag before the closing body tag rather than in a separate js file. But it seems like its not working at all and still comes in along with the picture.
What I did: http://jsfiddle.net/fuhs3smx/
Seems like its not working in Jsfiddle (new to this program) which is why I gave the link to the website so you'd guys atleast get an idea of what I'm trying to accomplish.
Guess what I'm trying to ask here is, where exactly should I place the script for 'slide.bs.carousel'? Everything looks good to me and my guess is that I'm placing the script in the wrong area.
<div id="carousel-example-generic" class="carousel slide carousel-fade" data-ride="carousel">
<!-- Indicators -->
<ol class="carousel-indicators">
<li data-target="#carousel-example-generic" data-slide-to="0" class="active"></li>
<li data-target="#carousel-example-generic" data-slide-to="1"></li>
<li data-target="#carousel-example-generic" data-slide-to="2"></li>
</ol>
<!-- Wrapper for slides -->
<div class="carousel-inner" role="listbox">
<div class="item active">
<img src="./img/family-new.jpg" alt="We are Serious about Clean!">
<div class="carousel-caption">
<h3>Safe for the whole family!</h3>
</div>
</div>
<div class="item">
<img src="./img/RugCleaningFacility.jpg" alt="Rug Cleaning">
<div class="carousel-caption">
<h3>State of the art rug cleaning facility!</h3>
</div>
</div>
<div class="item">
<img src="./img/ProfessionalWW.jpg" alt="Window Washing and Pressure Washing">
<div class="carousel-caption">
<h3>Professional Window Washing and Pressure Washing!</h3>
</div>
</div>
<div class="item">
<img src="./img/UpholsteryClean.jpg" alt="Upholstery Cleaning">
<div class="carousel-caption">
<h3>The deepest upholstery cleaning available!</h3>
</div>
</div>
</div>
<!-- Controls -->
<a class="left carousel-control" href="#carousel-example-generic" role="button" data-slide="prev">
<span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
<a class="right carousel-control" href="#carousel-example-generic" role="button" data-slide="next">
<span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div>
UPDATE: After including bootstrap.min.js, I'm getting this message when pulling up the dev tools:
Uncaught TypeError: undefined is not a function
carouselContainer.carousel({
interval: slideInterval,
cycle: true,
pause: "hover"
}).on('slid.bs.carousel', function() {
toggleCaption();
});
What does that mean? Maybe I've mispelled something or maybe the placement is all wrong.
Your fiddle doesn't include Bootstrap.js. You must also include jQuery as Bootstrap.js requires jQuery.
The Uncaught TypeError: jQuery.easing[this.easing] is not a function issue can be resolved by adding jQuery UI.
You'll noticed that I also placed your JS inside .ready() so that it's guaranteed to be executed after the DOM is ready.
I've updated the fiddle for you to review. http://jsfiddle.net/yongchuc/fuhs3smx/2/
I'm using the full slider bootstrap and would like to keep all the features, but instead of putting all images in the Carousel, I wonder if it is possible to keep only one and only change the background-image.
<!-- Full Page Image Background Carousel Header -->
<header id="myCarousel" class="carousel slide">
<!-- Indicators -->
<ol class="carousel-indicators">
<li data-target="#myCarousel" data-slide-to="0" class="active"></li>
<li data-target="#myCarousel" data-slide-to="1"></li>
<li data-target="#myCarousel" data-slide-to="2"></li>
</ol>
<!-- Wrapper for Slides -->
<div class="carousel-inner">
<div class="item active">
<!-- Set the first background image using inline CSS below. -->
<div class="fill" style="background-image:url('http://placehold.it/1900x1080&text=Slide One');"></div>
<div class="carousel-caption">
<h2>Caption 1</h2>
</div>
</div>
<div class="item">
<!-- Set the second background image using inline CSS below. -->
<div class="fill" style="background-image:url('http://placehold.it/1900x1080&text=Slide Two');"></div>
<div class="carousel-caption">
<h2>Caption 2</h2>
</div>
</div>
<div class="item">
<!-- Set the third background image using inline CSS below. -->
<div class="fill" style="background-image:url('http://placehold.it/1900x1080&text=Slide Three');"></div>
<div class="carousel-caption">
<h2>Caption 3</h2>
</div>
</div>
</div>
<!-- Controls -->
<a class="left carousel-control" href="#myCarousel" data-slide="prev">
<span class="icon-prev"></span>
</a>
<a class="right carousel-control" href="#myCarousel" data-slide="next">
<span class="icon-next"></span>
</a>
</header>
Finnaly:
<!-- Full Page Image Background Carousel Header -->
<header id="myCarousel" class="carousel slide">
<!-- Wrapper for Slides -->
<div class="carousel-inner">
<div class="item active">
<!-- Set the first background image using inline CSS below. -->
<div class="fill" **style="background-image:url('http://placehold.it/1900x1080&text=Slide One');"**></div>
<div class="carousel-caption">
<h2>Caption 1</h2>
</div>
</div>
</div>
<!-- Controls -->
<a class="left carousel-control" href="#myCarousel" data-slide="prev">
<span class="icon-prev"></span>
</a>
<a class="right carousel-control" href="#myCarousel" data-slide="next">
<span class="icon-next"></span>
</a>
</header>
I don't know why you would want this function, but since you're asking, I'll give you a solution.
With the .css()-selector in jQuery, you can target CSS and change it with jQuery.
You can create an array or variable, loop through it with .each(), store that information in another variable and then let jQuery change the background-image after some time or after an action. You can change the background by using the following jQuery:
$('.classname').css('background-image', 'variable');
Just as an example (you'll have to figure out yourself how to do it with the background-images, how to let jQuery display another one etc), I have set up this fiddle. In the fiddle, I have a variable, which I split on the | and which I then loop through with .each(). This variable (chunk) is later used to make some new divs with the respective chunk as a classname.
jQuery
var somestring = "img1|img2|img3",
separated = somestring.split("|");
$.each(separated, function(index, chunk) {
$('.test').append('<div class="' + chunk + '">' + chunk + '</div>');
//This line is purely added to do something with the chunks
});
I didn't want to make the whole code of you, since this site is made to help each other. I gave you a pretty good push to the right direction, you now just have to figure out how to change the background-image-property on a click or other action.
I have a strange behaviorin Bootstrap Carousel which I am using with AngularJS. Below is the HTML code where I am trying to dynamically add background color to each thumbnail. What I observe is the following:
Initially, the "active" part of carousel adds background color dynamically to each thumbnail as expected.
However, once I start rotating the carousel, all thumbnails lose their background color.
Now, when I reload the page, all thumbnails get background color again.
So I cannot understand what causing the loss of background color initially during rotation? Thanks.
<div class="well">
<div id="myCarousel" class="carousel slide">
<!-- Carousel items -->
<div class="carousel-inner">
<div ng-repeat="imgSet in imgSets" ng-class="{item: true, active : $first}">
<div ng-class="row">
<div ng-repeat="img in imgSet track by img.id" class="col-sm-3">
<a href="/appDetail/{{img.id}}" class="thumbnail" style="background-color: {{img.tile_color}};">
<img ng-src="{{uri}}/{{img.image}}" alt="Image" class="img-responsive" height="{{img.tile_height}}" width="{{img.tile_width}}">
</a>
</div>
</div>
<!--/row-->
</div>
<!--/item-->
</div>
<!--/carousel-inner-->
<a class="left carousel-control" href="#myCarousel" data-slide="prev">‹</a>
<a class="right carousel-control" href="#myCarousel" data-slide="next">›</a>
</div>
<!--/myCarousel-->
</div>
<!--/well-->
Well I found how to fix it, but I still do not understand why the original is not working (and why the fix is working):
my {{img.tile_color}} is a string of the form "#1956B7" (or any other #). I thought one must have "#" sign in front of the number. When I removed the "#" it started working.