From 67ff46a5e8974a30eaa6fd57c3084e906e024360 Mon Sep 17 00:00:00 2001 From: EATSTEAK Date: Sat, 7 Dec 2024 01:45:24 +0900 Subject: [PATCH 01/21] updated to React 19 --- docs/index.js | 10 ++++++---- docs/single-demo.js | 10 ++++++---- package.json | 14 +++++++------- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/docs/index.js b/docs/index.js index 763285354..a903857c0 100644 --- a/docs/index.js +++ b/docs/index.js @@ -1,13 +1,15 @@ "use strict"; import React from "react"; -import ReactDOM from "react-dom"; +import { createRoot } from "react-dom/client"; import Docs from "./docs"; +const container = document.getElementById("rapp"); +const root = createRoot(container); + React.initializeTouchEvents && React.initializeTouchEvents(true); -ReactDOM.render( +root.render( - , - document.getElementById("rapp") + ); diff --git a/docs/single-demo.js b/docs/single-demo.js index 81d7213e8..07929a1aa 100644 --- a/docs/single-demo.js +++ b/docs/single-demo.js @@ -1,7 +1,7 @@ "use strict"; import React from "react"; -import ReactDOM from "react-dom"; +import { createRoot } from "react-dom/client"; import Slider from "../src/slider"; import MultipleItems from "../examples/MultipleItems"; function SimpleSlider() { @@ -48,10 +48,12 @@ function App() { ); } +const container = document.getElementById("rapp"); +const root = createRoot(container); + React.initializeTouchEvents && React.initializeTouchEvents(true); -ReactDOM.render( +root.render( - , - document.getElementById("rapp") + ); diff --git a/package.json b/package.json index 508ec272a..8137c9cba 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ "@babel/preset-env": "^7.1.0", "@babel/preset-react": "^7.0.0", "@testing-library/jest-dom": "^5.16.4", - "@testing-library/react": "^13.3.0", + "@testing-library/react": "^16.1.0", "@testing-library/user-event": "^14.3.0", "autoprefixer": "^7.1.2", "babel-core": "^7.0.0-bridge.0", @@ -71,8 +71,9 @@ "postcss-loader": "^1.3.3", "prettier": "^1.14.3", "raf": "^3.4.0", - "react": "^18.0.0", - "react-dom": "^18.0.0", + "react": "^19.0.0", + "react-dom": "^19.0.0", + "regenerator-runtime": "^0.14.1", "sinon": "^2.1.0", "slick-carousel": "^1.8.1", "style-loader": "^0.16.1", @@ -80,8 +81,7 @@ "webpack": "^4.21.0", "webpack-cli": "^3.1.2", "webpack-dev-server": "^3.1.9", - "why-did-you-update": "^0.1.1", - "regenerator-runtime": "^0.14.1" + "why-did-you-update": "^0.1.1" }, "dependencies": { "classnames": "^2.2.5", @@ -91,8 +91,8 @@ "resize-observer-polyfill": "^1.5.0" }, "peerDependencies": { - "react": "^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0" + "react": "^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" }, "lint-staged": { "*.{js,json,md}": [ From d9202f263d95237b276c16f1b68593e12e8d66b0 Mon Sep 17 00:00:00 2001 From: Pero Date: Sun, 8 Dec 2024 19:08:16 +0800 Subject: [PATCH 02/21] Fix: vertical swiping does not work --- src/default-props.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/default-props.js b/src/default-props.js index 65f29d424..ed60a059a 100644 --- a/src/default-props.js +++ b/src/default-props.js @@ -50,6 +50,7 @@ let defaultProps = { useTransform: true, variableWidth: false, vertical: false, + verticalSwiping: false, waitForAnimate: true, asNavFor: null, unslick: false From f79e812044b50c8e953d5b1ae75b748e6f6ce14f Mon Sep 17 00:00:00 2001 From: akiran Date: Tue, 17 Dec 2024 13:37:54 +0530 Subject: [PATCH 03/21] released 0.30.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8137c9cba..2d2a9d834 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-slick", - "version": "0.30.2", + "version": "0.30.3", "description": " React port of slick carousel", "main": "./lib", "files": [ From 1c608da4145cdea800268000fc576879825821e8 Mon Sep 17 00:00:00 2001 From: akiran Date: Wed, 25 Dec 2024 22:23:22 +0530 Subject: [PATCH 04/21] integrate playwright --- .gitignore | 4 ++ package.json | 6 ++- playwright-ct.config.js | 47 ++++++++++++++++++++++++ playwright-tests/sample/sample.spec.tsx | 15 ++++++++ playwright-tests/sample/sample.story.tsx | 5 +++ playwright/index.html | 12 ++++++ playwright/index.jsx | 2 + 7 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 playwright-ct.config.js create mode 100644 playwright-tests/sample/sample.spec.tsx create mode 100644 playwright-tests/sample/sample.story.tsx create mode 100644 playwright/index.html create mode 100644 playwright/index.jsx diff --git a/.gitignore b/.gitignore index 735cbb4eb..b401c9047 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,7 @@ docs/fonts/ docs/ajax-loader.gif package-lock.json .DS_Store +/test-results/ +/playwright-report/ +/blob-report/ +/playwright/.cache/ diff --git a/package.json b/package.json index 2d2a9d834..a0b7fd3e7 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,9 @@ "precommit": "lint-staged", "test": "jest", "test-watch": "jest --watch", - "clear-jest": "jest --clearCache" + "clear-jest": "jest --clearCache", + "test-ct": "playwright test -c playwright-ct.config.js", + "test-clear": "jest --clearCache && rm -rf ./playwright/.cache" }, "author": "Kiran Abburi", "license": "MIT", @@ -43,9 +45,11 @@ "@babel/polyfill": "^7.0.0", "@babel/preset-env": "^7.1.0", "@babel/preset-react": "^7.0.0", + "@playwright/experimental-ct-react": "^1.49.1", "@testing-library/jest-dom": "^5.16.4", "@testing-library/react": "^16.1.0", "@testing-library/user-event": "^14.3.0", + "@types/node": "^22.10.2", "autoprefixer": "^7.1.2", "babel-core": "^7.0.0-bridge.0", "babel-jest": "^24.8.0", diff --git a/playwright-ct.config.js b/playwright-ct.config.js new file mode 100644 index 000000000..2f93a5779 --- /dev/null +++ b/playwright-ct.config.js @@ -0,0 +1,47 @@ +// @ts-check +const { defineConfig, devices } = require("@playwright/experimental-ct-react"); +/** + * @see https://playwright.dev/docs/test-configuration + */ +module.exports = defineConfig({ + testDir: "./playwright-tests", + // testDir: "./tests-out", + /* The base directory, relative to the config file, for snapshot files created with toMatchSnapshot and toHaveScreenshot. */ + snapshotDir: "./__snapshots__", + /* Maximum time one test can run for. */ + timeout: 10 * 1000, + /* Run tests in files in parallel */ + fullyParallel: true, + /* Fail the build on CI if you accidentally left test.only in the source code. */ + forbidOnly: !!process.env.CI, + /* Retry on CI only */ + retries: process.env.CI ? 2 : 0, + /* Opt out of parallel tests on CI. */ + workers: process.env.CI ? 1 : undefined, + /* Reporter to use. See https://playwright.dev/docs/test-reporters */ + reporter: "html", + /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ + use: { + /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ + trace: "on-first-retry", + + /* Port to use for Playwright component endpoint. */ + ctPort: 3100 + }, + + /* Configure projects for major browsers */ + projects: [ + { + name: "chromium", + use: { ...devices["Desktop Chrome"] } + } + // { + // name: "firefox", + // use: { ...devices["Desktop Firefox"] } + // }, + // { + // name: "webkit", + // use: { ...devices["Desktop Safari"] } + // } + ] +}); diff --git a/playwright-tests/sample/sample.spec.tsx b/playwright-tests/sample/sample.spec.tsx new file mode 100644 index 000000000..04d888e9d --- /dev/null +++ b/playwright-tests/sample/sample.spec.tsx @@ -0,0 +1,15 @@ +//Imports the test and expect functions from the Playwright ct-react module +import { test, expect } from "@playwright/experimental-ct-react"; +//Imports the App component to test from the relative ../App path +import App from "./sample.story"; + +//Configures the viewport to a 500x500 size +test.use({ viewport: { width: 500, height: 500 } }); +//Starts a test case named "should work" which will run asynchronously, +//mount function binding is destructured from test parameter +test("Sample playwright test", async ({ mount }) => { + //Uses mount() to instantiate the component in isolation + const component = await mount(); + //Asserts that component contains expected "Learn React" text on it verifying basic render. + await expect(component).toContainText("Learn React"); +}); diff --git a/playwright-tests/sample/sample.story.tsx b/playwright-tests/sample/sample.story.tsx new file mode 100644 index 000000000..1d3aef811 --- /dev/null +++ b/playwright-tests/sample/sample.story.tsx @@ -0,0 +1,5 @@ +import React from "react"; + +export default function App() { + return
Learn React
; +} diff --git a/playwright/index.html b/playwright/index.html new file mode 100644 index 000000000..2bf9f743a --- /dev/null +++ b/playwright/index.html @@ -0,0 +1,12 @@ + + + + + + Testing Page + + +
+ + + diff --git a/playwright/index.jsx b/playwright/index.jsx new file mode 100644 index 000000000..ac6de14bf --- /dev/null +++ b/playwright/index.jsx @@ -0,0 +1,2 @@ +// Import styles, initialize component theme here. +// import '../src/common.css'; From 482cbf3e0e98b059a48834f18f2c6cadee4dee29 Mon Sep 17 00:00:00 2001 From: akiran Date: Thu, 26 Dec 2024 17:36:59 +0530 Subject: [PATCH 05/21] removed enquire.js with window.matchMedia --- package.json | 1 - src/slider.js | 14 ++++++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index a0b7fd3e7..be73c4728 100644 --- a/package.json +++ b/package.json @@ -89,7 +89,6 @@ }, "dependencies": { "classnames": "^2.2.5", - "enquire.js": "^2.1.6", "json2mq": "^0.2.0", "lodash.debounce": "^4.0.8", "resize-observer-polyfill": "^1.5.0" diff --git a/src/slider.js b/src/slider.js index 36225013e..4cead187f 100644 --- a/src/slider.js +++ b/src/slider.js @@ -5,7 +5,6 @@ import { InnerSlider } from "./inner-slider"; import json2mq from "json2mq"; import defaultProps from "./default-props"; import { canUseDOM, filterSettings } from "./utils/innerSliderUtils"; -const enquire = canUseDOM() && require("enquire.js"); export default class Slider extends React.Component { constructor(props) { @@ -20,8 +19,15 @@ export default class Slider extends React.Component { media(query, handler) { // javascript handler for css media query - enquire.register(query, handler); - this._responsiveMediaHandlers.push({ query, handler }); + const mql = window.matchMedia(query); + const listener = ({ matches }) => { + if (matches) { + handler(); + } + }; + mql.addListener(listener); + // listener(mql); + this._responsiveMediaHandlers.push({ mql, query, listener }); } // handles responsive breakpoints @@ -69,7 +75,7 @@ export default class Slider extends React.Component { componentWillUnmount() { this._responsiveMediaHandlers.forEach(function(obj) { - enquire.unregister(obj.query, obj.handler); + obj.mql.removeListener(obj.listener); }); } From 3e10bb85d87a767848a6b026a9dd6eb61bbf6aee Mon Sep 17 00:00:00 2001 From: akiran Date: Thu, 26 Dec 2024 18:21:45 +0530 Subject: [PATCH 06/21] copy src files to src-jsx with jsx exntension for running playwright tests --- .gitignore | 1 + gulpfile.js | 9 +++++++++ package.json | 4 +++- 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index b401c9047..308ee06ad 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,4 @@ package-lock.json /playwright-report/ /blob-report/ /playwright/.cache/ +src-jsx diff --git a/gulpfile.js b/gulpfile.js index 2859e2b9f..4a7d036e7 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -2,6 +2,7 @@ var gulp = require("gulp"); var del = require("del"); +var rename = require("gulp-rename"); var webpack = require("webpack"); var WebpackDevServer = require("webpack-dev-server"); var assign = require("object-assign"); @@ -29,6 +30,14 @@ gulp.task("copy", function() { .pipe(gulp.dest("./build")); }); +gulp.task("prepare-playwright", function() { + // Copy files to src-jsx directory with jsx extension + return gulp + .src("./src/*.js") + .pipe(rename({ extname: ".jsx" })) + .pipe(gulp.dest("./src-jsx")); +}); + gulp.task( "watch", gulp.series(["copy"], function(done) { diff --git a/package.json b/package.json index be73c4728..55ee7e3b6 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,8 @@ "test-watch": "jest --watch", "clear-jest": "jest --clearCache", "test-ct": "playwright test -c playwright-ct.config.js", - "test-clear": "jest --clearCache && rm -rf ./playwright/.cache" + "test-clear": "jest --clearCache && rm -rf ./playwright/.cache", + "prepare-playwright": "rm -rf ./src-jsx && gulp prepare-playwright" }, "author": "Kiran Abburi", "license": "MIT", @@ -65,6 +66,7 @@ "express": "^4.14.0", "foundation-apps": "^1.2.0", "gulp": "^4.0.0", + "gulp-rename": "^2.0.0", "husky": "^0.14.3", "jest": "^28.1.3", "jest-environment-jsdom": "^28.1.3", From 4e4eaf327c49ae8c407b014bf9b26119d055989a Mon Sep 17 00:00:00 2001 From: akiran Date: Thu, 26 Dec 2024 20:39:32 +0530 Subject: [PATCH 07/21] playwright test for responsive feature --- gulpfile.js | 2 +- package.json | 2 +- .../features/responsive/responsive.spec.tsx | 41 +++++++++++ .../features/responsive/responsive.story.tsx | 71 +++++++++++++++++++ src/slider.js | 1 - 5 files changed, 114 insertions(+), 3 deletions(-) create mode 100644 playwright-tests/features/responsive/responsive.spec.tsx create mode 100644 playwright-tests/features/responsive/responsive.story.tsx diff --git a/gulpfile.js b/gulpfile.js index 4a7d036e7..9714f6530 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -33,7 +33,7 @@ gulp.task("copy", function() { gulp.task("prepare-playwright", function() { // Copy files to src-jsx directory with jsx extension return gulp - .src("./src/*.js") + .src("./src/**/*.js") .pipe(rename({ extname: ".jsx" })) .pipe(gulp.dest("./src-jsx")); }); diff --git a/package.json b/package.json index 55ee7e3b6..4b9c7d040 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "test": "jest", "test-watch": "jest --watch", "clear-jest": "jest --clearCache", - "test-ct": "playwright test -c playwright-ct.config.js", + "test-ct": "npm run prepare-playwright && playwright test -c playwright-ct.config.js", "test-clear": "jest --clearCache && rm -rf ./playwright/.cache", "prepare-playwright": "rm -rf ./src-jsx && gulp prepare-playwright" }, diff --git a/playwright-tests/features/responsive/responsive.spec.tsx b/playwright-tests/features/responsive/responsive.spec.tsx new file mode 100644 index 000000000..0d961609e --- /dev/null +++ b/playwright-tests/features/responsive/responsive.spec.tsx @@ -0,0 +1,41 @@ +import { test, expect } from "@playwright/experimental-ct-react"; +import Responsive from "./responsive.story"; + +test.use({ viewport: { width: 1200, height: 500 } }); + +async function activeSlidesCount(component) { + return await component.locator(".slick-slide.slick-active").count(); +} + +test("should work", async ({ mount, page }) => { + // const viewport = page.viewportSize(); + // await expect(viewport).toEqual(3); + + const component = await mount(); + + await expect(await activeSlidesCount(component)).toEqual(4); + + await page.setViewportSize({ width: 1000, height: 500 }); + await page.waitForTimeout(100); + await expect(await activeSlidesCount(component)).toEqual(3); + + await page.setViewportSize({ width: 600, height: 500 }); + await page.waitForTimeout(100); + await expect(await activeSlidesCount(component)).toEqual(2); + + await page.setViewportSize({ width: 400, height: 500 }); + await page.waitForTimeout(100); + await expect(await activeSlidesCount(component)).toEqual(1); + + await page.setViewportSize({ width: 600, height: 500 }); + await page.waitForTimeout(100); + await expect(await activeSlidesCount(component)).toEqual(2); + + await page.setViewportSize({ width: 1000, height: 500 }); + await page.waitForTimeout(100); + await expect(await activeSlidesCount(component)).toEqual(3); + + await page.setViewportSize({ width: 1500, height: 500 }); + await page.waitForTimeout(100); + await expect(await activeSlidesCount(component)).toEqual(4); +}); diff --git a/playwright-tests/features/responsive/responsive.story.tsx b/playwright-tests/features/responsive/responsive.story.tsx new file mode 100644 index 000000000..93fbe1ecf --- /dev/null +++ b/playwright-tests/features/responsive/responsive.story.tsx @@ -0,0 +1,71 @@ +import React from "react"; +import Slider from "../../../src-jsx"; + +function Responsive() { + var settings = { + dots: true, + infinite: false, + speed: 500, + slidesToShow: 4, + slidesToScroll: 4, + initialSlide: 0, + responsive: [ + { + breakpoint: 1024, + settings: { + slidesToShow: 3, + slidesToScroll: 3, + infinite: true, + dots: true + } + }, + { + breakpoint: 600, + settings: { + slidesToShow: 2, + slidesToScroll: 2, + initialSlide: 2 + } + }, + { + breakpoint: 480, + settings: { + slidesToShow: 1, + slidesToScroll: 1 + } + } + ] + }; + return ( +
+ +
+

1

+
+
+

2

+
+
+

3

+
+
+

4

+
+
+

5

+
+
+

6

+
+
+

7

+
+
+

8

+
+
+
+ ); +} + +export default Responsive; diff --git a/src/slider.js b/src/slider.js index 4cead187f..d4766b35a 100644 --- a/src/slider.js +++ b/src/slider.js @@ -26,7 +26,6 @@ export default class Slider extends React.Component { } }; mql.addListener(listener); - // listener(mql); this._responsiveMediaHandlers.push({ mql, query, listener }); } From 60159c2a1f6992da204467b90df7af073450df47 Mon Sep 17 00:00:00 2001 From: akiran Date: Thu, 26 Dec 2024 22:45:36 +0530 Subject: [PATCH 08/21] pass style props in unslick mode --- src/inner-slider.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/inner-slider.js b/src/inner-slider.js index e6efb784b..04426a71e 100644 --- a/src/inner-slider.js +++ b/src/inner-slider.js @@ -750,7 +750,7 @@ export class InnerSlider extends React.Component { if (this.props.unslick) { listProps = { className: "slick-list" }; - innerSliderProps = { className }; + innerSliderProps = { className, style: this.props.style }; } return (
From 5ac4077eb0f6f7b747d1633f4d34487e12eba13c Mon Sep 17 00:00:00 2001 From: akiran Date: Thu, 26 Dec 2024 22:55:17 +0530 Subject: [PATCH 09/21] remove extra space in vertical mode when no of slides is less than slides to show --- .../regression/fix-1930/fix-1930.spec.tsx | 14 +++++++++++++ .../regression/fix-1930/fix-1930.story.tsx | 21 +++++++++++++++++++ src/utils/innerSliderUtils.js | 4 +++- 3 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 playwright-tests/regression/fix-1930/fix-1930.spec.tsx create mode 100644 playwright-tests/regression/fix-1930/fix-1930.story.tsx diff --git a/playwright-tests/regression/fix-1930/fix-1930.spec.tsx b/playwright-tests/regression/fix-1930/fix-1930.spec.tsx new file mode 100644 index 000000000..963c85f8f --- /dev/null +++ b/playwright-tests/regression/fix-1930/fix-1930.spec.tsx @@ -0,0 +1,14 @@ +// Test fix of #1930: Extra height of slider in vertical mode when number of slides is less than or equal to slidesToShow + +import { test, expect } from "@playwright/experimental-ct-react"; +import VerticalMode from "./fix-1930.story"; + +test.use({ viewport: { width: 500, height: 500 } }); + +test("should work", async ({ mount }) => { + const component = await mount(); + + const track = component.locator(".slick-track").first(); + const box = await track.boundingBox(); + await expect(box.height).toEqual(200); +}); diff --git a/playwright-tests/regression/fix-1930/fix-1930.story.tsx b/playwright-tests/regression/fix-1930/fix-1930.story.tsx new file mode 100644 index 000000000..aa1bd0f11 --- /dev/null +++ b/playwright-tests/regression/fix-1930/fix-1930.story.tsx @@ -0,0 +1,21 @@ +import Slider from "../../../src-jsx"; +import React from "react"; + +export default function VerticalMode() { + const settings = { + dots: true, + infinite: false, + vertical: true, + slidesToShow: 3 + }; + return ( + +
+
1
+
+
+
2
+
+
+ ); +} diff --git a/src/utils/innerSliderUtils.js b/src/utils/innerSliderUtils.js index 98a37e917..db160143f 100644 --- a/src/utils/innerSliderUtils.js +++ b/src/utils/innerSliderUtils.js @@ -594,10 +594,12 @@ export const getTrackCSS = spec => { "slideWidth" ]); let trackWidth, trackHeight; - const trackChildren = spec.slideCount + 2 * spec.slidesToShow; if (!spec.vertical) { trackWidth = getTotalSlides(spec) * spec.slideWidth; } else { + const trackChildren = spec.unslick + ? spec.slideCount + : spec.slideCount + 2 * spec.slidesToShow; trackHeight = trackChildren * spec.slideHeight; } let style = { From 901840e3ed973be8b5235f8ce7cc5d5191bbeb26 Mon Sep 17 00:00:00 2001 From: akiran Date: Thu, 26 Dec 2024 23:59:38 +0530 Subject: [PATCH 10/21] unslick if slides <= slidesToShow --- .../regression/fix-1930/fix-1930.spec.tsx | 18 +++++++++++++--- .../regression/fix-1930/fix-1930.story.tsx | 21 ++++++++++++++++++- src/slider.js | 5 +---- 3 files changed, 36 insertions(+), 8 deletions(-) diff --git a/playwright-tests/regression/fix-1930/fix-1930.spec.tsx b/playwright-tests/regression/fix-1930/fix-1930.spec.tsx index 963c85f8f..91e0c1c79 100644 --- a/playwright-tests/regression/fix-1930/fix-1930.spec.tsx +++ b/playwright-tests/regression/fix-1930/fix-1930.spec.tsx @@ -1,12 +1,24 @@ // Test fix of #1930: Extra height of slider in vertical mode when number of slides is less than or equal to slidesToShow import { test, expect } from "@playwright/experimental-ct-react"; -import VerticalMode from "./fix-1930.story"; +import { VerticalModeFinite, VerticalModeInfinite } from "./fix-1930.story"; test.use({ viewport: { width: 500, height: 500 } }); -test("should work", async ({ mount }) => { - const component = await mount(); +test("height check in vertical mode when slides < slidesToShow and finite", async ({ + mount +}) => { + const component = await mount(); + + const track = component.locator(".slick-track").first(); + const box = await track.boundingBox(); + await expect(box.height).toEqual(200); +}); + +test("height check in vertical mode when slides < slidesToShow and infinite", async ({ + mount +}) => { + const component = await mount(); const track = component.locator(".slick-track").first(); const box = await track.boundingBox(); diff --git a/playwright-tests/regression/fix-1930/fix-1930.story.tsx b/playwright-tests/regression/fix-1930/fix-1930.story.tsx index aa1bd0f11..1246d4dcf 100644 --- a/playwright-tests/regression/fix-1930/fix-1930.story.tsx +++ b/playwright-tests/regression/fix-1930/fix-1930.story.tsx @@ -1,7 +1,7 @@ import Slider from "../../../src-jsx"; import React from "react"; -export default function VerticalMode() { +export function VerticalModeFinite() { const settings = { dots: true, infinite: false, @@ -19,3 +19,22 @@ export default function VerticalMode() { ); } + +export function VerticalModeInfinite() { + const settings = { + dots: true, + infinite: true, + vertical: true, + slidesToShow: 3 + }; + return ( + +
+
1
+
+
+
2
+
+
+ ); +} diff --git a/src/slider.js b/src/slider.js index d4766b35a..7fdbe4a13 100644 --- a/src/slider.js +++ b/src/slider.js @@ -203,10 +203,7 @@ export default class Slider extends React.Component { if (settings === "unslick") { const className = "regular slider " + (this.props.className || ""); return
{children}
; - } else if ( - newChildren.length <= settings.slidesToShow && - !settings.infinite - ) { + } else if (newChildren.length <= settings.slidesToShow) { settings.unslick = true; } return ( From f8b4745e2360ae7d83e88ca99b221d3acd1d0c47 Mon Sep 17 00:00:00 2001 From: akiran Date: Fri, 27 Dec 2024 16:43:57 +0530 Subject: [PATCH 11/21] exclude playwright tests from jest --- jest.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jest.config.js b/jest.config.js index 0ef9b2852..2750160c6 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,5 +1,5 @@ module.exports = { testEnvironment: "jsdom", setupFilesAfterEnv: ["/test-setup.js"], - testPathIgnorePatterns: ["/node_modules/", "e2e-tests"] + testPathIgnorePatterns: ["/node_modules/", "playwright-tests"] }; From 5bf7a6b3fcaa98fe2f94866a3a30921034eafd21 Mon Sep 17 00:00:00 2001 From: akiran Date: Fri, 27 Dec 2024 17:13:13 +0530 Subject: [PATCH 12/21] Fixed tests --- __tests__/regression/fix-1813.test.js | 217 +++++++++++++------------- test-utils.js | 11 ++ 2 files changed, 122 insertions(+), 106 deletions(-) diff --git a/__tests__/regression/fix-1813.test.js b/__tests__/regression/fix-1813.test.js index 5b4722259..9adbcfb7e 100644 --- a/__tests__/regression/fix-1813.test.js +++ b/__tests__/regression/fix-1813.test.js @@ -1,4 +1,5 @@ //Test fix of #1813: In infinite mode, when slidesToShow equal to the length of slides, infinite functionality is not working. +// Reversed the fix for #1813 to match the slick carousel functionality. When slides <= slidesToShow, unslick will be activated import React from "react"; import { render, fireEvent } from "@testing-library/react"; @@ -13,7 +14,9 @@ import { getButtonsLength, getClonesCount, getCurrentSlide, - getSlidesCount + getSlidesCount, + hasArrows, + hasDots } from "../../test-utils"; import { GenericSliderComponent } from "../TestComponents"; @@ -29,23 +32,13 @@ function MultipleItems() { } describe("Multiple Items with slidesToShow = slides count in infinite mode", function() { - it("should have 9 actual slides and (9(pre) + 9(post)) clone slides", function() { - //Todo: Need to fix extra clones - const { container } = render(); - expect(getSlidesCount(container)).toEqual(27); - expect(getClonesCount(container)).toEqual(18); - }); it("should have 9 active slides", function() { const { container } = render(); expect(getActiveSlidesCount(container)).toEqual(9); }); - it("should have 3 dots", function() { - const { container } = render(); - expect(getButtonsLength(container)).toEqual(3); - }); it("should show first 9 slides", function() { const { container } = render(); - expect(getActiveButton(container)).toEqual(["1"]); + //expect(getActiveButton(container)).toEqual(["1"]); expect(getActiveSlidesText(container)).toEqual([ "1", "2", @@ -58,102 +51,114 @@ describe("Multiple Items with slidesToShow = slides count in infinite mode", fun "9" ]); }); - it("should show slides from 4 when next button is clicked", function() { + it("shouldn't have any arrows", () => { const { container } = render(); - clickNext(container); - expect(getActiveButton(container)).toEqual(["2"]); - expect(getActiveSlidesText(container)).toEqual([ - "4", - "5", - "6", - "7", - "8", - "9", - "1", - "2", - "3" - ]); + expect(hasArrows(container)).toEqual(false); }); - it("should show slides from 7 when previous button is clicked", function() { + it("shouldn't have any dots", () => { const { container } = render(); - clickPrevious(container); - expect(getActiveButton(container)).toEqual(["3"]); - expect(getActiveSlidesText(container)).toEqual([ - "7", - "8", - "9", - "1", - "2", - "3", - "4", - "5", - "6" - ]); - }); - it("should show slides first 9 slides when first dot is clicked", function() { - const { container } = render(); - fireEvent( - getButtons(container)[0], - new MouseEvent("click", { - bubbles: true, - cancelable: true - }) - ); - expect(getActiveButton(container)).toEqual(["1"]); - expect(getActiveSlidesText(container)).toEqual([ - "1", - "2", - "3", - "4", - "5", - "6", - "7", - "8", - "9" - ]); - }); - it("should show slides from 4 when middle dot is clicked", function() { - const { container } = render(); - fireEvent( - getButtons(container)[1], - new MouseEvent("click", { - bubbles: true, - cancelable: true - }) - ); - expect(getActiveButton(container)).toEqual(["2"]); - expect(getActiveSlidesText(container)).toEqual([ - "4", - "5", - "6", - "7", - "8", - "9", - "1", - "2", - "3" - ]); - }); - it("should show slides from 7 when last dot is clicked", function() { - const { container } = render(); - fireEvent( - getButtons(container)[2], - new MouseEvent("click", { - bubbles: true, - cancelable: true - }) - ); - expect(getActiveButton(container)).toEqual(["3"]); - expect(getActiveSlidesText(container)).toEqual([ - "7", - "8", - "9", - "1", - "2", - "3", - "4", - "5", - "6" - ]); + expect(hasDots(container)).toEqual(false); }); + // it("should have 0 dots", function() { + // const { container } = render(); + // expect(getButtonsLength(container)).toEqual(0); + // }); + // it("should show slides from 4 when next button is clicked", function() { + // const { container } = render(); + // clickNext(container); + // expect(getActiveButton(container)).toEqual(["2"]); + // expect(getActiveSlidesText(container)).toEqual([ + // "4", + // "5", + // "6", + // "7", + // "8", + // "9", + // "1", + // "2", + // "3" + // ]); + // }); + // it("should show slides from 7 when previous button is clicked", function() { + // const { container } = render(); + // clickPrevious(container); + // expect(getActiveButton(container)).toEqual(["3"]); + // expect(getActiveSlidesText(container)).toEqual([ + // "7", + // "8", + // "9", + // "1", + // "2", + // "3", + // "4", + // "5", + // "6" + // ]); + // }); + // it("should show slides first 9 slides when first dot is clicked", function() { + // const { container } = render(); + // fireEvent( + // getButtons(container)[0], + // new MouseEvent("click", { + // bubbles: true, + // cancelable: true + // }) + // ); + // expect(getActiveButton(container)).toEqual(["1"]); + // expect(getActiveSlidesText(container)).toEqual([ + // "1", + // "2", + // "3", + // "4", + // "5", + // "6", + // "7", + // "8", + // "9" + // ]); + // }); + // it("should show slides from 4 when middle dot is clicked", function() { + // const { container } = render(); + // fireEvent( + // getButtons(container)[1], + // new MouseEvent("click", { + // bubbles: true, + // cancelable: true + // }) + // ); + // expect(getActiveButton(container)).toEqual(["2"]); + // expect(getActiveSlidesText(container)).toEqual([ + // "4", + // "5", + // "6", + // "7", + // "8", + // "9", + // "1", + // "2", + // "3" + // ]); + // }); + // it("should show slides from 7 when last dot is clicked", function() { + // const { container } = render(); + // fireEvent( + // getButtons(container)[2], + // new MouseEvent("click", { + // bubbles: true, + // cancelable: true + // }) + // ); + // expect(getActiveButton(container)).toEqual(["3"]); + // expect(getActiveSlidesText(container)).toEqual([ + // "7", + // "8", + // "9", + // "1", + // "2", + // "3", + // "4", + // "5", + // "6" + // ]); + // }); }); diff --git a/test-utils.js b/test-utils.js index 265b79bfb..1f689291f 100644 --- a/test-utils.js +++ b/test-utils.js @@ -84,3 +84,14 @@ export function clickPrevious(container) { }) ); } + +export function hasDots(container) { + return Boolean(container.querySelectorAll(".slick-dots")[0]); +} + +export function hasArrows(container) { + return Boolean( + container.getElementsByClassName("slick-next")[0] || + container.getElementsByClassName("slick-prev")[0] + ); +} From 143b524f60e2bec82be771f677b76a5b8559e0fe Mon Sep 17 00:00:00 2001 From: akiran Date: Fri, 27 Dec 2024 21:39:37 +0530 Subject: [PATCH 13/21] fixed #2414: No clones when there is one slide or unslick=true --- __tests__/regression/fix-2414.test.js | 64 +++++++++++++++++++++++++++ src/track.js | 7 ++- 2 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 __tests__/regression/fix-2414.test.js diff --git a/__tests__/regression/fix-2414.test.js b/__tests__/regression/fix-2414.test.js new file mode 100644 index 000000000..069122861 --- /dev/null +++ b/__tests__/regression/fix-2414.test.js @@ -0,0 +1,64 @@ +// Test fix of #2414: Extra clones in infinite mode when there is only one slide or unslick is true +import React from "react"; +import { render, fireEvent } from "@testing-library/react"; + +import { + getCurrentSlideContent, + getSlidesCount, + getActiveSlidesCount, + getClonesCount, + hasArrows, + hasDots +} from "../../test-utils"; +import { GenericSliderComponent } from "../TestComponents"; + +function SliderWithOneSlide() { + const settings = { + dots: true, + infinite: true + }; + return ; +} + +function SliderWithUnslick() { + const settings = { + dots: true, + infinite: true, + unslick: true + // slidesToShow: 2 + }; + return ; +} + +describe("Slider with one slide", function() { + it("should have 1 active slide", function() { + const { container } = render(); + expect(getActiveSlidesCount(container)).toEqual(1); + }); + it("should not have any clones", function() { + const { container } = render(); + expect(getClonesCount(container)).toEqual(0); + }); + it("should no have dots and arrows", function() { + const { container } = render(); + expect(hasArrows(container)).toEqual(false); + expect(hasDots(container)).toEqual(false); + }); +}); + +describe("Slider with unslick=true", function() { + // Remove skip on this test after fixing the unslick issue + it.skip("should have all slides active", function() { + const { container } = render(); + expect(getActiveSlidesCount(container)).toEqual(2); + }); + it("should not have any clones", function() { + const { container } = render(); + expect(getClonesCount(container)).toEqual(0); + }); + it("should no have dots and arrows", function() { + const { container } = render(); + expect(hasArrows(container)).toEqual(false); + expect(hasDots(container)).toEqual(false); + }); +}); diff --git a/src/track.js b/src/track.js index d3c92f2f6..b64e722e7 100644 --- a/src/track.js +++ b/src/track.js @@ -136,7 +136,12 @@ const renderSlides = spec => { ); // if slide needs to be precloned or postcloned - if (spec.infinite && spec.fade === false) { + if ( + spec.infinite && + childrenCount > 1 && + spec.fade === false && + !spec.unslick + ) { let preCloneNo = childrenCount - index; if (preCloneNo <= getPreClones(spec)) { key = -preCloneNo; From 148f7bbd543826b7842e27a43c59babd337e26ab Mon Sep 17 00:00:00 2001 From: akiran Date: Fri, 27 Dec 2024 22:22:51 +0530 Subject: [PATCH 14/21] updated tests --- __tests__/regression/fix-2414.test.js | 6 ++---- .../features/responsive/responsive.spec.tsx | 17 +++++++---------- 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/__tests__/regression/fix-2414.test.js b/__tests__/regression/fix-2414.test.js index 069122861..41413c72c 100644 --- a/__tests__/regression/fix-2414.test.js +++ b/__tests__/regression/fix-2414.test.js @@ -25,7 +25,6 @@ function SliderWithUnslick() { dots: true, infinite: true, unslick: true - // slidesToShow: 2 }; return ; } @@ -47,10 +46,9 @@ describe("Slider with one slide", function() { }); describe("Slider with unslick=true", function() { - // Remove skip on this test after fixing the unslick issue - it.skip("should have all slides active", function() { + it("should have one active slide", function() { const { container } = render(); - expect(getActiveSlidesCount(container)).toEqual(2); + expect(getActiveSlidesCount(container)).toEqual(1); }); it("should not have any clones", function() { const { container } = render(); diff --git a/playwright-tests/features/responsive/responsive.spec.tsx b/playwright-tests/features/responsive/responsive.spec.tsx index 0d961609e..e32c33bac 100644 --- a/playwright-tests/features/responsive/responsive.spec.tsx +++ b/playwright-tests/features/responsive/responsive.spec.tsx @@ -7,35 +7,32 @@ async function activeSlidesCount(component) { return await component.locator(".slick-slide.slick-active").count(); } -test("should work", async ({ mount, page }) => { - // const viewport = page.viewportSize(); - // await expect(viewport).toEqual(3); - +test("Responsive settings", async ({ mount, page }) => { const component = await mount(); await expect(await activeSlidesCount(component)).toEqual(4); await page.setViewportSize({ width: 1000, height: 500 }); - await page.waitForTimeout(100); + await page.waitForTimeout(10); await expect(await activeSlidesCount(component)).toEqual(3); await page.setViewportSize({ width: 600, height: 500 }); - await page.waitForTimeout(100); + await page.waitForTimeout(10); await expect(await activeSlidesCount(component)).toEqual(2); await page.setViewportSize({ width: 400, height: 500 }); - await page.waitForTimeout(100); + await page.waitForTimeout(10); await expect(await activeSlidesCount(component)).toEqual(1); await page.setViewportSize({ width: 600, height: 500 }); - await page.waitForTimeout(100); + await page.waitForTimeout(10); await expect(await activeSlidesCount(component)).toEqual(2); await page.setViewportSize({ width: 1000, height: 500 }); - await page.waitForTimeout(100); + await page.waitForTimeout(10); await expect(await activeSlidesCount(component)).toEqual(3); await page.setViewportSize({ width: 1500, height: 500 }); - await page.waitForTimeout(100); + await page.waitForTimeout(10); await expect(await activeSlidesCount(component)).toEqual(4); }); From 7356a3ae739dda1b100781c624364ec8da76b866 Mon Sep 17 00:00:00 2001 From: akiran Date: Sat, 8 Feb 2025 18:57:33 +0530 Subject: [PATCH 15/21] removed jquery react compate tests --- __tests__/jQSlickUtils.js | 133 ----------------------------- __tests__/mount/centerMode.test.js | 78 ----------------- __tests__/mount/lazyLoad.test.js | 78 ----------------- __tests__/mount/live.test.js | 77 ----------------- __tests__/mount/simple.test.js | 80 ----------------- __tests__/reactSlickUtils.js | 107 ----------------------- 6 files changed, 553 deletions(-) delete mode 100644 __tests__/jQSlickUtils.js delete mode 100644 __tests__/mount/centerMode.test.js delete mode 100644 __tests__/mount/lazyLoad.test.js delete mode 100644 __tests__/mount/live.test.js delete mode 100644 __tests__/mount/simple.test.js delete mode 100644 __tests__/reactSlickUtils.js diff --git a/__tests__/jQSlickUtils.js b/__tests__/jQSlickUtils.js deleted file mode 100644 index e8d2ff77b..000000000 --- a/__tests__/jQSlickUtils.js +++ /dev/null @@ -1,133 +0,0 @@ -// this is for fetching details after initializing react and jquery slicks -// and compare those details to see if things are going different - -import { - createSliderReact, - createJQuerySliderChildren, - activeSlideInLastTransition -} from "./testUtils"; -import $ from "jquery"; -import * as slickCarousel from "slick-carousel"; -import util from "util"; -import js_beautify, { html as html_beautify } from "js-beautify"; - -// simulates actions from given actions object -// takes document from the scope from where it's called -function simulateActions(actions) { - if (actions.clickNext) { - for (let click = 0; click < actions.clickNext; click++) { - $(".slick-next").click(); - } - } - if (actions.clickPrev) { - for (let click = 0; click < actions.clickPrev; click++) { - $(".slick-prev").click(); - } - } - if (actions.clickSequence) { - for (let click of actions.clickSequence) { - if (click === "n") { - $(".slick-next").click(); - } else if (click === "p") { - $(".slick-prev").click(); - } else { - // that's right, you can't even write n/p properly - } - } - } -} - -// takes an object of keys and returns those details -/* Possible keys can be one of the following - currentSlide(index and value), activeSlides(index and value), - allSlides(index and value), clonedSlides(index and value) - */ -function fetchDetails(keys) { - let details = {}; - let currentSlide = null, - activeSlides = [], - allSlides = [], - clonedSlides = [], - visibleSlides = []; - for (let slide of $("div.slick-slide")) { - const slideObj = { - index: $(slide).attr("data-slick-index"), - value: $(slide) - .find("div") - .find("div") - .find("h3") - .text() - }; - allSlides.push(slideObj); - if ($(slide).hasClass("slick-current")) { - currentSlide = slideObj.index; - } - if ($(slide).hasClass("slick-active")) { - activeSlides.push(slideObj); - } - if ($(slide).hasClass("slick-cloned")) { - clonedSlides.push(slideObj); - } - if ($(slide).attr("aria-hidden") == "false") { - visibleSlides.push(slideObj); - } - } - if (keys.currentSlide) { - details.currentSlide = currentSlide; - } - if (keys.activeSlides) { - details.activeSlides = activeSlides; - } - if (keys.allSlides) { - details.allSlides = allSlides; - } - if (keys.clonedSlides) { - details.clonedSlides = clonedSlides; - } - if (keys.visibleSlides) { - details.visibleSlides = visibleSlides; - } - return details; -} - -// creates a jQuery slick with given settings and -// performs the given actions -// returns the given keys -export function getJQuerySlickDetails(settings, actions, keys) { - // create new slider - document.body.innerHTML = ` -
- ${createJQuerySliderChildren(settings.noOfSlides)} -
- `; - $(".regular.slider").slick({ - ...settings - }); - simulateActions(actions); - // console.log(html_beautify($('.regular.slider').html())) - return fetchDetails(keys); -} - -const settings = { - infinite: true, - noOfSlides: 5, - slidesToShow: 3, - slidesToScroll: 2, - useCSS: false, - speed: 0 -}; -const actions = { - clickNext: 2, - clickPrev: 1, - clickSequence: ["n", "p", "n"] -}; -const keys = { - activeSlides: true, - visibleSlides: true, - allSlides: true -}; - -test("testing getJQuerySlickDetails utility", () => { - const details = getJQuerySlickDetails(settings, actions, keys); - expect(details.activeSlides).toEqual(details.visibleSlides); -}); diff --git a/__tests__/mount/centerMode.test.js b/__tests__/mount/centerMode.test.js deleted file mode 100644 index aab6601d5..000000000 --- a/__tests__/mount/centerMode.test.js +++ /dev/null @@ -1,78 +0,0 @@ -import { getJQuerySlickDetails } from "../jQSlickUtils"; -import { getReactSlickDetails } from "../reactSlickUtils"; - -let settings = { - infinite: true, - speed: 0, - useCSS: false, - noOfSlides: 5, - slidesToShow: 3, - slidesToScroll: 1, - centerMode: true -}; -let actions = { - clickNext: 0, - clickPrev: 0, - clickSequence: [] -}; -let keys = { - currentSlide: true, - activeSlides: true, - clonedSlides: true, - allSlides: true -}; - -const testsUtil = (settings, actions, keys) => { - const jqDetails = getJQuerySlickDetails(settings, actions, keys); - const reactDetails = getReactSlickDetails(settings, actions, keys); - test("checking current slide jQuery vs react", () => { - expect(reactDetails.currentSlide).toEqual(parseInt(jqDetails.currentSlide)); - }); - test("checking active slides jQuery vs react", () => { - expect(reactDetails.activeSlides).toEqual(jqDetails.activeSlides); - }); - - // Following two tests fail - test("checking cloned slides jQuery vs react", () => { - expect(reactDetails.clonedSlides.map(slide => slide.index)).toEqual( - jqDetails.clonedSlides.map(slide => slide.index) - ); - }); - test("checking all slides jQuery vs react", () => { - expect(reactDetails.allSlides.map(slide => slide.index)).toEqual( - jqDetails.allSlides.map(slide => slide.index) - ); - }); -}; - -describe("InnerSlider component tests: Part 1", () => { - testsUtil(settings, actions, keys); -}); -describe("InnerSlider component tests: Part 2", () => { - settings.slidesToScroll = 2; - testsUtil(settings, actions, keys); -}); -describe("InnerSlider component tests: Part 3", () => { - actions.clickNext = 2; - testsUtil(settings, actions, keys); -}); -describe("InnerSlider component tests: Part 4", () => { - actions.clickPrev = 2; - testsUtil(settings, actions, keys); -}); -describe("InnerSlider component tests: Part 5", () => { - actions.clickNext = 6; - testsUtil(settings, actions, keys); -}); -describe("InnerSlider component tests: Part 6", () => { - actions.clickPrev = 6; - testsUtil(settings, actions, keys); -}); -describe("InnerSlider component tests: Part 7", () => { - actions.clickSequence = ["n", "n", "n", "n", "n", "n", "p", "p", "p"]; - testsUtil(settings, actions, keys); -}); -describe("InnerSlider component tests: Part 8", () => { - actions.clickSequence = ["p", "p", "p", "p", "p", "p", "n", "n", "n"]; - testsUtil(settings, actions, keys); -}); diff --git a/__tests__/mount/lazyLoad.test.js b/__tests__/mount/lazyLoad.test.js deleted file mode 100644 index 33674a794..000000000 --- a/__tests__/mount/lazyLoad.test.js +++ /dev/null @@ -1,78 +0,0 @@ -import { getJQuerySlickDetails } from "../jQSlickUtils"; -import { getReactSlickDetails } from "../reactSlickUtils"; - -let settings = { - infinite: true, - speed: 0, - useCSS: false, - lazyLoad: true, - noOfSlides: 5, - slidesToShow: 3, - slidesToScroll: 1 -}; -let actions = { - clickNext: 0, - clickPrev: 0, - clickSequence: [] -}; -let keys = { - currentSlide: true, - activeSlides: true, - clonedSlides: true, - allSlides: true -}; - -const testsUtil = (settings, actions, keys) => { - const jqDetails = getJQuerySlickDetails(settings, actions, keys); - const reactDetails = getReactSlickDetails(settings, actions, keys); - test.skip("checking current slide jQuery vs react", () => { - expect(reactDetails.currentSlide).toEqual(parseInt(jqDetails.currentSlide)); - }); - test.skip("checking active slides jQuery vs react", () => { - expect(reactDetails.activeSlides).toEqual(jqDetails.activeSlides); - }); - - // Following two tests fail - test("checking cloned slides jQuery vs react", () => { - expect(reactDetails.clonedSlides.map(slide => slide.index)).toEqual( - jqDetails.clonedSlides.map(slide => slide.index) - ); - }); - test("checking all slides jQuery vs react", () => { - expect(reactDetails.allSlides.map(slide => slide.index)).toEqual( - jqDetails.allSlides.map(slide => slide.index) - ); - }); -}; - -describe("InnerSlider component tests with lazyload: Part 1", () => { - testsUtil(settings, actions, keys); -}); -describe("InnerSlider component tests with lazyload: Part 2", () => { - settings.slidesToScroll = 2; - testsUtil(settings, actions, keys); -}); -describe("InnerSlider component tests with lazyload: Part 3", () => { - actions.clickNext = 2; - testsUtil(settings, actions, keys); -}); -describe("InnerSlider component tests with lazyload: Part 4", () => { - actions.clickPrev = 2; - testsUtil(settings, actions, keys); -}); -describe("InnerSlider component tests with lazyload: Part 5", () => { - actions.clickNext = 6; - testsUtil(settings, actions, keys); -}); -describe("InnerSlider component tests with lazyload: Part 6", () => { - actions.clickPrev = 6; - testsUtil(settings, actions, keys); -}); -describe("InnerSlider component tests with lazyload: Part 7", () => { - actions.clickSequence = ["n", "n", "n", "n", "n", "n", "p", "p", "p"]; - testsUtil(settings, actions, keys); -}); -describe("InnerSlider component tests with lazyload: Part 8", () => { - actions.clickSequence = ["p", "p", "p", "p", "p", "p", "n", "n", "n"]; - testsUtil(settings, actions, keys); -}); diff --git a/__tests__/mount/live.test.js b/__tests__/mount/live.test.js deleted file mode 100644 index 069a457d9..000000000 --- a/__tests__/mount/live.test.js +++ /dev/null @@ -1,77 +0,0 @@ -import { getJQuerySlickDetails } from "../jQSlickUtils"; -import { getReactSlickDetails } from "../reactSlickUtils"; - -describe("live testing module", () => { - let settings = { - infinite: true, - speed: 0, - useCSS: false, - noOfSlides: 5, - slidesToShow: 3, - slidesToScroll: 1 - // centerMode: true, - }; - let actions = { - clickNext: 0, - clickPrev: 0, - clickSequence: [] - }; - let keys = { - // currentSlide: true, - // activeSlides: true, - clonedSlides: true - // allSlides: true, - }; - let reactDetails = getReactSlickDetails(settings, actions, keys); - let jqueryDetails = getJQuerySlickDetails(settings, actions, keys); - - // for(let noOfSlides of [5, 12]){ - // for (let slidesToShow of [1, 11, 12]){ - // for (let slidesToScroll of [1, 2, 11, 12]){ - - // for(let noOfSlides of [2, 3, 5, 6, 12]){ - // for (let slidesToShow of [1, 2, 3, 5, 11, 12]){ - // for (let slidesToScroll of [1, 2, 3, 5, 11, 12]){ - // if(noOfSlides < slidesToShow || noOfSlides < slidesToScroll || slidesToShow < slidesToScroll){ - // continue; - // } - // settings.noOfSlides = noOfSlides - // settings.slidesToShow = slidesToShow - // settings.slidesToScroll = slidesToScroll - // const jqueryDetails = getJQuerySlickDetails(settings, actions, keys) - // const reactDetails = getReactSlickDetails(settings, actions, keys) - // // test('number of cloned slides', () => { - // // expect(jqueryDetails.clonedSlides.filter(slide => slide.index < 0).length).toEqual( - // // noOfSlides === slidesToShow ? 0 : (settings.centerMode ? slidesToShow+1 : slidesToShow) - // // ) - // // expect(jqueryDetails.clonedSlides.filter(slide => slide.index >= 0).length).toEqual( - // // noOfSlides === slidesToShow ? 0 : noOfSlides - // // ) - // // }) - - // test('number of cloned slides, react vs jquery', () => { - // expect(reactDetails.clonedSlides.filter(slide => slide.index < 0).length).toEqual( - // jqueryDetails.clonedSlides.filter(slide => slide.index < 0).length - // ) - // expect(reactDetails.clonedSlides.filter(slide => slide.index >= 0).length).toEqual( - // jqueryDetails.clonedSlides.filter(slide => slide.index >= 0).length - // ) - // }) - - // // console.log( - // // 'settings:', settings, '\n', - // // 'pre:', jqueryDetails.clonedSlides.filter(slide => slide.index < 0).length, - // // 'post:', jqueryDetails.clonedSlides.filter(slide => slide.index >= 0).length - // // ) - // // console.log( - // // 'settings2:', settings.noOfSlides, '\n', - // // 'details2:', reactDetails.clonedSlides - // // .filter(slide => slide.index > 0).length - // // ) - // } - // } - // } - test("fake test", () => { - expect(1).toBe(1); - }); -}); diff --git a/__tests__/mount/simple.test.js b/__tests__/mount/simple.test.js deleted file mode 100644 index 9b9001f78..000000000 --- a/__tests__/mount/simple.test.js +++ /dev/null @@ -1,80 +0,0 @@ -import { getJQuerySlickDetails } from "../jQSlickUtils"; -import { getReactSlickDetails } from "../reactSlickUtils"; - -let settings = { - infinite: true, - speed: 0, - useCSS: false, - noOfSlides: 5, - slidesToShow: 3, - slidesToScroll: 1 -}; -let actions = { - clickNext: 0, - clickPrev: 0, - clickSequence: [] -}; -let keys = { - currentSlide: true, - activeSlides: true, - clonedSlides: true, - allSlides: true -}; - -const testsUtil = (settings, actions, keys) => { - const jqDetails = getJQuerySlickDetails(settings, actions, keys); - const reactDetails = getReactSlickDetails(settings, actions, keys); - test("checking current slide jQuery vs react", () => { - expect(reactDetails.currentSlide).toEqual(parseInt(jqDetails.currentSlide)); - }); - test("checking active slides jQuery vs react", () => { - expect(reactDetails.activeSlides).toEqual(jqDetails.activeSlides); - }); - - // Following two tests fail - test("checking cloned slides jQuery vs react", () => { - expect(reactDetails.clonedSlides.map(slide => slide.index)).toEqual( - jqDetails.clonedSlides.map(slide => slide.index) - ); - }); - test("checking all slides jQuery vs react", () => { - expect(reactDetails.allSlides.map(slide => slide.index)).toEqual( - jqDetails.allSlides.map(slide => slide.index) - ); - }); -}; - -describe("InnerSlider component tests: Part 1", () => { - testsUtil(settings, actions, keys); -}); -describe("InnerSlider component tests: Part 2", () => { - settings.slidesToScroll = 2; - testsUtil(settings, actions, keys); -}); -describe("InnerSlider component tests: Part 3", () => { - actions.clickNext = 2; - testsUtil(settings, actions, keys); -}); -describe("InnerSlider component tests: Part 4", () => { - actions.clickPrev = 2; - testsUtil(settings, actions, keys); -}); -describe("InnerSlider component tests: Part 5", () => { - actions.clickNext = 6; - testsUtil(settings, actions, keys); -}); -describe("InnerSlider component tests: Part 6", () => { - actions.clickPrev = 6; - testsUtil(settings, actions, keys); -}); -describe("InnerSlider component tests: Part 7", () => { - actions.clickSequence = ["n", "n", "n", "n", "n", "n", "p", "p", "p"]; - testsUtil(settings, actions, keys); -}); - -//TODO: old tests used this sequence `actions.clickSequence = ["p", "p", "p", "p", "p", "p", "n", "n", "n"];` -// Debug why tests failing with that sequence -describe("InnerSlider component tests: Part 8", () => { - actions.clickSequence = ["p", "p", "p", "p", "p", "p", "p", "n", "n", "n"]; - testsUtil(settings, actions, keys); -}); diff --git a/__tests__/reactSlickUtils.js b/__tests__/reactSlickUtils.js deleted file mode 100644 index 9daa3c85a..000000000 --- a/__tests__/reactSlickUtils.js +++ /dev/null @@ -1,107 +0,0 @@ -import { - clickNext, - clickPrevious, - getSlides, - getCurrentSlide, - hasClass, - getClonesCount -} from "../test-utils"; -import { createInnerSliderWrapper } from "./testUtils"; - -// given slider and actions objects, and simulates given actions -function simulateActions(slider, actions) { - if (actions.clickNext) { - for (let click = 0; click < actions.clickNext; click++) { - clickNext(slider); - } - } - if (actions.clickPrev) { - for (let click = 0; click < actions.clickPrev; click++) { - clickPrevious(slider); - } - } - if (actions.clickSequence) { - for (let click of actions.clickSequence) { - if (click === "n") { - clickNext(slider); - } else if (click === "p") { - clickPrevious(slider); - } else { - // not a valid action for now - } - } - } - // console.log('after simulating actions, state of slider:', slider.state()) -} - -function fetchDetails(container, keys) { - let details = { ...fetchDOMDetails(container, keys) }; - if (keys.currentSlide) { - // details.currentSlide = getCurrentSlide(container).textContent; - details.currentSlide = parseInt( - getCurrentSlide(container).getAttribute("data-index") - ); - } - return details; -} - -function fetchDOMDetails(slider, keys) { - let details = {}; - let currentSlide = null, - activeSlides = [], - allSlides = [], - clonedSlides = [], - visibleSlides = []; // currently no way to find these - //Array.from(getSlides(slider)).forEach(e=>console.log(Array.from(e.getElementsByTagName("h3")).length)); - Array.from(getSlides(slider)).forEach((slide, index) => { - const slideObj = { - index: slide.getAttribute("data-index"), - value: - Array.from(slide.getElementsByTagName("h3")).length === 1 - ? slide.querySelector("h3").textContent - : "..." - }; - allSlides.push(slideObj); - if (hasClass(slide, "slick-current")) { - currentSlide = slideObj; - } - if (hasClass(slide, "slick-active")) { - activeSlides.push(slideObj); - } - if (hasClass(slide, "slick-cloned")) { - clonedSlides.push(slideObj); - } - }); - if (keys.currentSlide) { - details.currentSlide = currentSlide; - } - if (keys.activeSlides) { - details.activeSlides = activeSlides; - } - if (keys.allSlides) { - details.allSlides = allSlides; - } - if (keys.clonedSlides) { - details.clonedSlides = clonedSlides; - } - if (keys.visibleSlides) { - details.visibleSlides = visibleSlides; - } - return details; -} - -export function getReactSlickDetails(settings, actions, keys) { - const slider = createInnerSliderWrapper(settings); - simulateActions(slider, actions); - return fetchDetails(slider, keys); -} - -/* -settings: [...sliderProps, noOfSlides], -actions: [clickNext, clickPrev, clickSequence], -keys: [currentSlide, activeSlides, clonedSlides, allSlides, visibleSlides] -*/ - -test("fake test", () => { - expect(1).toBe(1); -}); From 93dbaa6e58e283eb8c7e399d996c749a046129b9 Mon Sep 17 00:00:00 2001 From: akiran Date: Mon, 5 May 2025 11:10:37 +0530 Subject: [PATCH 16/21] fix to remove extra clones --- __tests__/regression/fix-2315.test.js | 2 +- src/track.js | 46 ++++++++++++++------------- src/utils/innerSliderUtils.js | 6 +++- 3 files changed, 30 insertions(+), 24 deletions(-) diff --git a/__tests__/regression/fix-2315.test.js b/__tests__/regression/fix-2315.test.js index 193cf464f..0be8f43f6 100644 --- a/__tests__/regression/fix-2315.test.js +++ b/__tests__/regression/fix-2315.test.js @@ -30,6 +30,6 @@ describe("State change in parent component of slider", () => { ); // Throws an error "Maximum update depth exceeded." if the bug exists expect(getCurrentSlideContent(container)).toEqual("1"); - expect(getSlidesCount(container)).toEqual(13); + expect(getSlidesCount(container)).toEqual(8); }); }); diff --git a/src/track.js b/src/track.js index b64e722e7..33ecc41ea 100644 --- a/src/track.js +++ b/src/track.js @@ -5,7 +5,8 @@ import classnames from "classnames"; import { lazyStartIndex, lazyEndIndex, - getPreClones + getPreClones, + getPostClones } from "./utils/innerSliderUtils"; // given specifications/props for a slide, fetch all the classes that need to be applied to the slide @@ -166,28 +167,29 @@ const renderSlides = spec => { }) ); } - - key = childrenCount + index; - if (key < endIndex) { - child = elem; - } - slideClasses = getSlideClasses({ ...spec, index: key }); - postCloneSlides.push( - React.cloneElement(child, { - key: "postcloned" + getKey(child, key), - "data-index": key, - tabIndex: "-1", - className: classnames(slideClasses, slideClass), - "aria-hidden": !slideClasses["slick-active"], - style: { ...(child.props.style || {}), ...childStyle }, - onClick: e => { - child.props && child.props.onClick && child.props.onClick(e); - if (spec.focusOnSelect) { - spec.focusOnSelect(childOnClickOptions); + if (index < getPostClones(spec)) { + key = childrenCount + index; + if (key < endIndex) { + child = elem; + } + slideClasses = getSlideClasses({ ...spec, index: key }); + postCloneSlides.push( + React.cloneElement(child, { + key: "postcloned" + getKey(child, key), + "data-index": key, + tabIndex: "-1", + className: classnames(slideClasses, slideClass), + "aria-hidden": !slideClasses["slick-active"], + style: { ...(child.props.style || {}), ...childStyle }, + onClick: e => { + child.props && child.props.onClick && child.props.onClick(e); + if (spec.focusOnSelect) { + spec.focusOnSelect(childOnClickOptions); + } } - } - }) - ); + }) + ); + } } }); diff --git a/src/utils/innerSliderUtils.js b/src/utils/innerSliderUtils.js index db160143f..8b6f6dee6 100644 --- a/src/utils/innerSliderUtils.js +++ b/src/utils/innerSliderUtils.js @@ -790,7 +790,11 @@ export const getPostClones = spec => { if (spec.unslick || !spec.infinite) { return 0; } - return spec.slideCount; + + if (spec.variableWidth) { + return spec.slideCount; + } + return spec.slidesToShow + (spec.centerMode ? 1 : 0); }; export const getTotalSlides = spec => From 057c02cf006446e994355958b633ee12f45059c6 Mon Sep 17 00:00:00 2001 From: akiran Date: Fri, 9 May 2025 09:49:10 +0530 Subject: [PATCH 17/21] removed sample tests --- examples/__tests__/sample.test.js | 40 ------------------------------- 1 file changed, 40 deletions(-) delete mode 100644 examples/__tests__/sample.test.js diff --git a/examples/__tests__/sample.test.js b/examples/__tests__/sample.test.js deleted file mode 100644 index d2d276e62..000000000 --- a/examples/__tests__/sample.test.js +++ /dev/null @@ -1,40 +0,0 @@ -import React from "react"; -import { fireEvent, render } from "@testing-library/react"; - -export default class Counter extends React.Component { - constructor(props) { - super(props); - this.state = { - count: 0 - }; - } - render() { - return ( - - ); - } -} - -describe("sample counter test", function() { - it("mutliple counts", function() { - const { container } = render(); - const button = container.getElementsByTagName("Button")[0]; - fireEvent( - button, - new MouseEvent("click", { - bubbles: true, - cancelable: true - }) - ); - fireEvent( - button, - new MouseEvent("click", { - bubbles: true, - cancelable: true - }) - ); - expect(button.textContent).toEqual("Count 2"); - }); -}); From 9ba9df4152d427b5d911b2bc52ef79904579b31e Mon Sep 17 00:00:00 2001 From: akiran Date: Wed, 14 May 2025 11:34:10 +0530 Subject: [PATCH 18/21] fixed clone test --- examples/__tests__/CentreMode.test.js | 4 ++-- examples/__tests__/MultipleItems.test.js | 6 +++--- examples/__tests__/SimpleSlider.test.js | 6 +++--- examples/__tests__/UnevenSets.test.js | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/examples/__tests__/CentreMode.test.js b/examples/__tests__/CentreMode.test.js index d2c3c5191..5ccab1f1e 100644 --- a/examples/__tests__/CentreMode.test.js +++ b/examples/__tests__/CentreMode.test.js @@ -17,8 +17,8 @@ describe("CenterMode Tests", () => { let totalSlides = getSlidesCount(container); let clonedSlides = getClonesCount(container); let activeSlides = getActiveSlidesCount(container); - expect(totalSlides).toEqual(16); - expect(clonedSlides).toEqual(10); + expect(totalSlides).toEqual(14); + expect(clonedSlides).toEqual(8); expect(activeSlides).toEqual(3); //expect(beautify_html(toString(container))).toMatchSnapshot(); }); diff --git a/examples/__tests__/MultipleItems.test.js b/examples/__tests__/MultipleItems.test.js index 1adc83daa..334929811 100644 --- a/examples/__tests__/MultipleItems.test.js +++ b/examples/__tests__/MultipleItems.test.js @@ -20,10 +20,10 @@ import { import MultipleItems from "../MultipleItems"; describe("Multiple Items", function() { - it("should have 9 actual slides and (3(pre) + 9(post)) clone slides", function() { + it("should have 9 actual slides and (3(pre) + 3(post)) clone slides", function() { const { container } = render(); - expect(getSlidesCount(container)).toEqual(21); - expect(getClonesCount(container)).toEqual(12); + expect(getSlidesCount(container)).toEqual(15); + expect(getClonesCount(container)).toEqual(6); //expect(beautify_html(toString(container))).toMatchSnapshot(); }); it("should have 3 active slides", function() { diff --git a/examples/__tests__/SimpleSlider.test.js b/examples/__tests__/SimpleSlider.test.js index 71402cbbb..b63b4775d 100644 --- a/examples/__tests__/SimpleSlider.test.js +++ b/examples/__tests__/SimpleSlider.test.js @@ -17,12 +17,12 @@ import { describe("SimpleSlider example", () => { it("should have 13 slides (1(preclone) + 6(actual) + 6(postclone))", function() { - const { container } = render(); - expect(container.getElementsByClassName("slick-slide").length).toBe(13); + const { container } = render(); + expect(container.getElementsByClassName("slick-slide").length).toBe(8); }); it("should have 7 clone slides", function() { const { container } = render(); - expect(container.getElementsByClassName("slick-cloned").length).toBe(7); + expect(container.getElementsByClassName("slick-cloned").length).toBe(2); }); it("should have 1 current slide", function() { const { container } = render(); diff --git a/examples/__tests__/UnevenSets.test.js b/examples/__tests__/UnevenSets.test.js index eff2f9dcf..0f4ed92a9 100644 --- a/examples/__tests__/UnevenSets.test.js +++ b/examples/__tests__/UnevenSets.test.js @@ -82,8 +82,8 @@ describe("UnevenSets Infinite", () => { let clonedSlides = getClonesCount(container); let activeSlides = getActiveSlidesCount(container); let dots = getButtonsLength(container); - expect(totalSlides).toEqual(16); - expect(clonedSlides).toEqual(10); + expect(totalSlides).toEqual(14); + expect(clonedSlides).toEqual(8); expect(activeSlides).toEqual(4); expect(dots).toEqual(2); // expect(beautify_html(toString(container))).toMatchSnapshot(); From dabd4adfbddbf9413634c513c9c0c9aeba34da9c Mon Sep 17 00:00:00 2001 From: akiran Date: Wed, 14 May 2025 11:49:30 +0530 Subject: [PATCH 19/21] updated jest config to add react-slick alias --- docs/single-demo.js | 75 +++++++++++++------------ examples/__tests__/SimpleSlider.test.js | 2 +- jest.config.js | 5 +- 3 files changed, 45 insertions(+), 37 deletions(-) diff --git a/docs/single-demo.js b/docs/single-demo.js index 07929a1aa..afeb33d6e 100644 --- a/docs/single-demo.js +++ b/docs/single-demo.js @@ -4,46 +4,51 @@ import React from "react"; import { createRoot } from "react-dom/client"; import Slider from "../src/slider"; import MultipleItems from "../examples/MultipleItems"; -function SimpleSlider() { - const settings = { - dots: true, - infinite: true, - speed: 500, - slidesToShow: 1, - slidesToScroll: 1 - }; - return ( -
-

Single Item

- -
-

1

-
-
-

2

-
-
-

3

-
-
-

4

-
-
-

5

-
-
-

6

-
-
-
- ); -} +import SimpleSlider from "../examples/SimpleSlider"; +import CenterMode from "../examples/CenterMode"; +import UnevenSetsInfinite from "../examples/UnevenSetsInfinite"; +// function SimpleSlider() { +// const settings = { +// dots: true, +// infinite: true, +// speed: 500, +// slidesToShow: 1, +// slidesToScroll: 1 +// }; +// return ( +//
+//

Single Item

+// +//
+//

1

+//
+//
+//

2

+//
+//
+//

3

+//
+//
+//

4

+//
+//
+//

5

+//
+//
+//

6

+//
+//
+//
+// ); +// } function App() { return (
{/* */} - + {/* */} + {/* */} +
); } diff --git a/examples/__tests__/SimpleSlider.test.js b/examples/__tests__/SimpleSlider.test.js index b63b4775d..682004fc8 100644 --- a/examples/__tests__/SimpleSlider.test.js +++ b/examples/__tests__/SimpleSlider.test.js @@ -16,7 +16,7 @@ import { } from "../../test-utils"; describe("SimpleSlider example", () => { - it("should have 13 slides (1(preclone) + 6(actual) + 6(postclone))", function() { + it("should have 13 slides (1(preclone) + 6(actual) + 1(postclone))", function() { const { container } = render(); expect(container.getElementsByClassName("slick-slide").length).toBe(8); }); diff --git a/jest.config.js b/jest.config.js index 2750160c6..08914c16b 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,5 +1,8 @@ module.exports = { testEnvironment: "jsdom", setupFilesAfterEnv: ["/test-setup.js"], - testPathIgnorePatterns: ["/node_modules/", "playwright-tests"] + testPathIgnorePatterns: ["/node_modules/", "playwright-tests"], + moduleNameMapper: { + "react-slick": "/src/index.js" + } }; From cfbd65e82701158cd2d7ecd7535747c0829e04b6 Mon Sep 17 00:00:00 2001 From: akiran Date: Thu, 7 Aug 2025 10:51:57 +0530 Subject: [PATCH 20/21] increase wait time in responsive playwright tests --- .../features/responsive/responsive.spec.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/playwright-tests/features/responsive/responsive.spec.tsx b/playwright-tests/features/responsive/responsive.spec.tsx index e32c33bac..7e6c05580 100644 --- a/playwright-tests/features/responsive/responsive.spec.tsx +++ b/playwright-tests/features/responsive/responsive.spec.tsx @@ -13,26 +13,26 @@ test("Responsive settings", async ({ mount, page }) => { await expect(await activeSlidesCount(component)).toEqual(4); await page.setViewportSize({ width: 1000, height: 500 }); - await page.waitForTimeout(10); + await page.waitForTimeout(100); await expect(await activeSlidesCount(component)).toEqual(3); await page.setViewportSize({ width: 600, height: 500 }); - await page.waitForTimeout(10); + await page.waitForTimeout(100); await expect(await activeSlidesCount(component)).toEqual(2); await page.setViewportSize({ width: 400, height: 500 }); - await page.waitForTimeout(10); + await page.waitForTimeout(100); await expect(await activeSlidesCount(component)).toEqual(1); await page.setViewportSize({ width: 600, height: 500 }); - await page.waitForTimeout(10); + await page.waitForTimeout(100); await expect(await activeSlidesCount(component)).toEqual(2); await page.setViewportSize({ width: 1000, height: 500 }); - await page.waitForTimeout(10); + await page.waitForTimeout(100); await expect(await activeSlidesCount(component)).toEqual(3); await page.setViewportSize({ width: 1500, height: 500 }); - await page.waitForTimeout(10); + await page.waitForTimeout(100); await expect(await activeSlidesCount(component)).toEqual(4); }); From 97442318e9a442bd4a84eb25133ef62087f98232 Mon Sep 17 00:00:00 2001 From: akiran Date: Thu, 7 Aug 2025 10:56:04 +0530 Subject: [PATCH 21/21] release 0.31.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4b9c7d040..83d5dd94c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-slick", - "version": "0.30.3", + "version": "0.31.0", "description": " React port of slick carousel", "main": "./lib", "files": [