diff --git a/extensions/amp-carousel/0.1/slidescroll.js b/extensions/amp-carousel/0.1/slidescroll.js index f6a02f92c730..655e3a1f5888 100644 --- a/extensions/amp-carousel/0.1/slidescroll.js +++ b/extensions/amp-carousel/0.1/slidescroll.js @@ -521,6 +521,11 @@ export class AmpSlideScroll extends BaseSlides { * @return {number} a number representing the next slide index. */ getNextSlideIndex_(currentScrollLeft) { + // Addresses race where slideWidth is 0, due to being hidden + // while snapping is occuring. + if (!currentScrollLeft && !this.slideWidth_) { + return 0; + } // This can be only 0, 1 or 2, since only a max of 3 slides are shown at // a time. const scrolledSlideIndex = Math.round(currentScrollLeft / this.slideWidth_); diff --git a/extensions/amp-carousel/0.1/test/test-slidescroll.js b/extensions/amp-carousel/0.1/test/test-slidescroll.js index 1b8ba8dd20d3..175bdd977254 100644 --- a/extensions/amp-carousel/0.1/test/test-slidescroll.js +++ b/extensions/amp-carousel/0.1/test/test-slidescroll.js @@ -1271,6 +1271,17 @@ describes.realWin( expect(showSlideSpy).to.have.been.calledWith(4); }); + it('should handle carousel snapping & hiding race', async () => { + const ampSlideScroll = await getAmpSlideScroll(true); + const impl = await ampSlideScroll.getImpl(); + + // simluate carousel hidding + impl.slideWidth_ = 0; + + // simulate snapping + expect(impl.getNextSlideIndex_(0)).to.equal(0); + }); + it('should NOT call showSlide_ before layout', async () => { const ampSlideScroll = await getAmpSlideScroll( true,