diff --git a/.github/workflows/cypress.yml b/.github/workflows/cypress.yml deleted file mode 100644 index 1c1fc1ec..00000000 --- a/.github/workflows/cypress.yml +++ /dev/null @@ -1,53 +0,0 @@ -name: Cypress Tests - -on: - push: - branches: - - main - pull_request: - branches: - - main - - -jobs: - cypress-run: - runs-on: ubuntu-latest - container: - image: cypress/browsers:node16.16.0-chrome107-ff107 - options: --user 1001 - - steps: - - name: Checkout - uses: actions/checkout@v2 - - - uses: pnpm/action-setup@v2.2.2 - with: - version: 7 - - - uses: actions/setup-node@v2 - with: - node-version: ${{ matrix.node-version }} - - - name: Install dependencies - run: pnpm install - - - name: Build nuka-carousel - run: pnpm build - - - name: Install the Cypress binary - run: npx cypress install - - # - name: Cypress run - # run: pnpm run test:ci-with-server - - - uses: actions/upload-artifact@v3 - if: failure() - with: - name: cypress-screenshots - path: ./packages/nuka/cypress/screenshots - - - uses: actions/upload-artifact@v3 - if: always() - with: - name: cypress-videos - path: ./packages/nuka/cypress/videos diff --git a/package.json b/package.json index 85ca4cea..f721e852 100644 --- a/package.json +++ b/package.json @@ -10,10 +10,6 @@ "lint:fix": "pnpm run --parallel lint --fix", "start:storybook": "pnpm run --filter nuka-carousel storybook", "start:website": "pnpm run --filter website start", - "test": "pnpm run -r test", - "test:ci": "pnpm run -r test:ci", - "test:ci-with-server": "start-server-and-test start:website http://localhost:3000 test:ci", - "test:storybook-with-server": "start-server-and-test start:storybook http://localhost:3000 test:storybook", "test:storybook": "pnpm run --filter nuka-carousel test:storybook", "check": "pnpm run lint", "check:ci": "pnpm run check", diff --git a/packages/nuka/cypress/e2e/standard-carousel.cy.ts b/packages/nuka/cypress/e2e/standard-carousel.cy.ts deleted file mode 100644 index 270dd172..00000000 --- a/packages/nuka/cypress/e2e/standard-carousel.cy.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { assertVisibleSlide, navigateToNextSlide } from '../support/util'; - -describe('Standard Carousel', () => { - const stdDemoSel = '.standard-demo '; - - it('should render carousel with 5 slides and only 1 visible slide and go through all of the slides', () => { - cy.visitCarousel(); - - cy.get(stdDemoSel + '.slider-container').should( - 'have.attr', - 'aria-label', - 'Carousel Demo' - ); - - assertVisibleSlide(stdDemoSel, 1); - - cy.get(stdDemoSel + '.paging-item').should('have.length', 5); - - cy.get(stdDemoSel + 'button[aria-label="Go to previous slide"]').should( - 'be.disabled' - ); - - /** - * Navigate through the entire carousel and verify the buttons - * are enabled until the last slide. - */ - - navigateToNextSlide(stdDemoSel); - assertVisibleSlide(stdDemoSel, 2); - - navigateToNextSlide(stdDemoSel); - assertVisibleSlide(stdDemoSel, 3); - - navigateToNextSlide(stdDemoSel); - assertVisibleSlide(stdDemoSel, 4); - - navigateToNextSlide(stdDemoSel); - assertVisibleSlide(stdDemoSel, 5); - - cy.get(stdDemoSel + 'button[aria-label="Go to next slide"]').should( - 'be.disabled' - ); - }); - - it('should be a landmark region', () => { - const params = { - carouselId: 'region-carousel', - landmark: true, - }; - - const url = `http://localhost:3000/open-source/nuka-carousel?params='${JSON.stringify( - params - )}'`; - - cy.visit(url); - - cy.get(stdDemoSel + '.slider-container') - .should('have.attr', 'aria-label', 'Carousel Demo') - .should('have.attr', 'role', 'region') - .and('have.attr', 'aria-roledescription', 'carousel'); - }); -}); diff --git a/packages/nuka/cypress/e2e/swipe-gestures-carousel.cy.ts b/packages/nuka/cypress/e2e/swipe-gestures-carousel.cy.ts deleted file mode 100644 index 8ead0036..00000000 --- a/packages/nuka/cypress/e2e/swipe-gestures-carousel.cy.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { assertVisibleSlide } from '../support/util'; - -describe('Swipe Carousel', () => { - const carouselWidth = 750; - const stdDemoSel = '.standard-demo '; - - it('should navigate the carousel using swipe gestures', () => { - const distance = carouselWidth / 2; - - cy.visitCarousel(); - - assertVisibleSlide(stdDemoSel, 1); - - cy.swipeSlider(stdDemoSel, distance); - assertVisibleSlide(stdDemoSel, 2); - - cy.swipeSlider(stdDemoSel, distance); - assertVisibleSlide(stdDemoSel, 3); - - cy.swipeSlider(stdDemoSel, -distance); - assertVisibleSlide(stdDemoSel, 2); - }); - - it('should not navigate the carousel using incomplete swipe gestures', () => { - cy.visitCarousel(); - - assertVisibleSlide(stdDemoSel, 1); - - /** - * An incomplete gesture at a standard intertia should not navigate to the next slide - */ - cy.swipeSlider(stdDemoSel, carouselWidth / 4); - assertVisibleSlide(stdDemoSel, 1); - - cy.swipeSlider(stdDemoSel, carouselWidth / 2); - assertVisibleSlide(stdDemoSel, 2); - - /** - * An incomplete gesture at a standard intertia should not navigate to the previous slide - */ - cy.swipeSlider(stdDemoSel, -carouselWidth / 4); - assertVisibleSlide(stdDemoSel, 2); - }); - - it('should navigate the carousel small quick gestures', () => { - cy.visitCarousel(); - - assertVisibleSlide(stdDemoSel, 1); - - cy.swipeSlider(stdDemoSel, carouselWidth / 4, { waitMs: 90 }); - assertVisibleSlide(stdDemoSel, 2); - - /** - * Perform a reverse swipe to verify it works going backwards - */ - cy.swipeSlider(stdDemoSel, -carouselWidth / 4, { waitMs: 90 }); - assertVisibleSlide(stdDemoSel, 1); - }); -}); diff --git a/packages/nuka/cypress/e2e/wrap-around-carousel.cy.ts b/packages/nuka/cypress/e2e/wrap-around-carousel.cy.ts deleted file mode 100644 index e7bae648..00000000 --- a/packages/nuka/cypress/e2e/wrap-around-carousel.cy.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { - assertVisibleSlide, - navigateToNextSlide, - navigateToPreviousSlide, -} from '../support/util'; - -describe('Wrap-Around Carousel', () => { - const waDemoSel = '.wrap-around-demo '; - - it('should render carousel with 5 slides and only 1 visible slide and go through all of the slides', () => { - cy.visitCarousel(); - - cy.get('li').contains('Wrap Around').click(); - - cy.get(waDemoSel + '.slider-container').should( - 'have.attr', - 'aria-label', - 'Carousel Demo' - ); - - assertVisibleSlide(waDemoSel, 1); - - cy.get(waDemoSel + '.paging-item').should('have.length', 5); - - /** - * Click through to the final slide and verify it shows - * and the next button is still enabled. - */ - - cy.get(waDemoSel + 'button[aria-label="Go to previous slide"]').should( - 'be.not.disabled' - ); - navigateToNextSlide(waDemoSel); - navigateToNextSlide(waDemoSel); - navigateToNextSlide(waDemoSel); - navigateToNextSlide(waDemoSel); - assertVisibleSlide(waDemoSel, 5); - - /** - * Click next slide to see if it can go from 5 -> 1 - * and the next previous is still enabled. - */ - - navigateToNextSlide(waDemoSel); - assertVisibleSlide(waDemoSel, 1); - - /** - * Click previous slide to see if it can go from 1 -> 5 again - */ - - navigateToPreviousSlide(waDemoSel); - assertVisibleSlide(waDemoSel, 5); - }); -}); diff --git a/packages/nuka/cypress/fixtures/example.json b/packages/nuka/cypress/fixtures/example.json deleted file mode 100644 index 02e42543..00000000 --- a/packages/nuka/cypress/fixtures/example.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "Using fixtures to represent data", - "email": "hello@cypress.io", - "body": "Fixtures are a great way to mock data for responses to routes" -} diff --git a/packages/nuka/cypress/plugins/index.ts b/packages/nuka/cypress/plugins/index.ts deleted file mode 100644 index 258d858a..00000000 --- a/packages/nuka/cypress/plugins/index.ts +++ /dev/null @@ -1,22 +0,0 @@ -// / <reference types="cypress" /> -// *********************************************************** -// This example plugins/index.js can be used to load plugins -// -// You can change the location of this file or turn off loading -// the plugins file with the 'pluginsFile' configuration option. -// -// You can read more here: -// https://on.cypress.io/plugins-guide -// *********************************************************** - -// This function is called when a project is opened or re-opened (e.g. due to -// the project's config changing) - -/** - * @type {Cypress.PluginConfig} - */ -// eslint-disable-next-line @typescript-eslint/no-unused-vars -module.exports = (on, config) => { - // `on` is used to hook into various events Cypress emits - // `config` is the resolved Cypress config -}; diff --git a/packages/nuka/cypress/support/commands.ts b/packages/nuka/cypress/support/commands.ts deleted file mode 100644 index 119ab03f..00000000 --- a/packages/nuka/cypress/support/commands.ts +++ /dev/null @@ -1,25 +0,0 @@ -// *********************************************** -// This example commands.js shows you how to -// create various custom commands and overwrite -// existing commands. -// -// For more comprehensive examples of custom -// commands please read more here: -// https://on.cypress.io/custom-commands -// *********************************************** -// -// -// -- This is a parent command -- -// Cypress.Commands.add('login', (email, password) => { ... }) -// -// -// -- This is a child command -- -// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... }) -// -// -// -- This is a dual command -- -// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... }) -// -// -// -- This will overwrite an existing command -- -// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... }) diff --git a/packages/nuka/cypress/support/e2e.ts b/packages/nuka/cypress/support/e2e.ts deleted file mode 100644 index 714ec844..00000000 --- a/packages/nuka/cypress/support/e2e.ts +++ /dev/null @@ -1,85 +0,0 @@ -// *********************************************************** -// This example support/index.js is processed and -// loaded automatically before your test files. -// -// This is a great place to put global configuration and -// behavior that modifies Cypress. -// -// You can change the location of this file or turn off -// automatically serving support files with the -// 'supportFile' configuration option. -// -// You can read more here: -// https://on.cypress.io/configuration -// *********************************************************** - -// Import commands.js using ES2015 syntax: -import './commands'; - -// Alternatively you can use CommonJS syntax: -// require('./commands') - -// Custom command typings, based on documentation at -// https://docs.cypress.io/guides/tooling/typescript-support#Types-for-Custom-Commands -declare global { - // eslint-disable-next-line @typescript-eslint/no-namespace - namespace Cypress { - interface Chainable { - /** - * Opens the dev site with a carousel set to the designated props. - */ - visitCarousel(): ReturnType<typeof cy.visit>; - /** - * Simulates a swipe gesture on the carousel - * @param distance - the distance (px) to swipe from right to left (or - * left to right if negative) - */ - swipeSlider( - selector: string, - distance: number, - options?: { waitMs?: number } - ): ReturnType<typeof cy.visit>; - } - } -} - -Cypress.Commands.add('visitCarousel', () => { - cy.visit(`http://localhost:3000/open-source/nuka-carousel`); -}); - -Cypress.Commands.add( - 'swipeSlider', - (selector: string, distance, { waitMs = 1000 } = {}) => { - const [start, end] = - distance >= 0 ? [distance, 0] : [0, Math.abs(distance)]; - - // Mock out the Date object so we can precisely simulate gesture event - // timing. Cypress' timing is too flaky due to its UI checks to be reliable - // on the millisecond level. - cy.clock(Date.UTC(2018, 10, 30), ['Date']); - - cy.get(selector + '.slider-container') - .trigger('mousedown', { which: 1 }) - .trigger('mousemove', { clientX: start }) - .then(function () { - this.clock.tick(waitMs - 1); - }) - .trigger('mousemove', { - // Add in one extra move event prior to the final one to fill the - // position buffer used to calculate inertia, so that calls with waitMs - // longer than 100ms (the maximum the position buffer keeps) will get - // proper velocity calculations. We use linear interpolation to - // determine a point that is consistent with a swipe of constant speed - // from start to end. - clientX: start + ((waitMs - 1) / waitMs) * (end - start), - }) - .then(function () { - this.clock.tick(1); - }) - .trigger('mousemove', { clientX: end }) - .trigger('mouseup') - .then(function () { - this.clock.restore(); - }); - } -); diff --git a/packages/nuka/cypress/support/util.ts b/packages/nuka/cypress/support/util.ts deleted file mode 100644 index 6e2ba76f..00000000 --- a/packages/nuka/cypress/support/util.ts +++ /dev/null @@ -1,31 +0,0 @@ -/* eslint-disable cypress/no-unnecessary-waiting */ -const waitThreshold = 100; - -export const assertVisibleSlide = (demoId: string, slideNumber: number) => { - cy.get(demoId + '.slide.slide-visible') - .should('have.length', 1) - .find('div') - .should('have.attr', 'data-slide', `Slide ${slideNumber}`); -}; - -export const navigateToNextSlide = (demoId: string) => { - cy.get(demoId + 'button[aria-label="Go to next slide"]') - .should('not.be.disabled') - .click(); - cy.wait(waitThreshold); -}; - -export const navigateToPreviousSlide = (demoId: string) => { - cy.get(demoId + 'button[aria-label="Go to previous slide"]') - .should('not.be.disabled') - .click(); - cy.wait(waitThreshold); -}; - -export const getSliderXOffset = ($sliderList: JQuery<HTMLElement>) => { - const parentElementOffset = - $sliderList[0].parentElement.getBoundingClientRect().left; - const sliderListOffset = $sliderList[0].getBoundingClientRect().left; - - return sliderListOffset - parentElementOffset; -}; diff --git a/packages/nuka/cypress/tsconfig.json b/packages/nuka/cypress/tsconfig.json deleted file mode 100644 index 18edb199..00000000 --- a/packages/nuka/cypress/tsconfig.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "compilerOptions": { - "target": "es5", - "lib": ["es5", "dom"], - "types": ["cypress", "node"] - }, - "include": ["**/*.ts"] -} diff --git a/packages/nuka/src/Carousel/CarouselTests.stories.tsx b/packages/nuka/src/Carousel/CarouselTests.stories.tsx index 2093697e..91c1b4ff 100644 --- a/packages/nuka/src/Carousel/CarouselTests.stories.tsx +++ b/packages/nuka/src/Carousel/CarouselTests.stories.tsx @@ -90,6 +90,8 @@ export const Slide: Story = { play: async ({ canvasElement }) => { const canvas = within(canvasElement); + const overflow = canvas.getByTestId('overflow'); + await expect(canvas.getByTestId('wrapper').classList).toContain( 'slide__with-gap' ); @@ -98,9 +100,9 @@ export const Slide: Story = { await userEvent.click(forwardButton); await waitFor(async () => { - expect(canvas.getByTestId('overflow').scrollLeft).toEqual( + expect(overflow.scrollLeft).toEqual( (canvas.getByTestId('wrapper').children[1] as HTMLElement).offsetLeft - - canvas.getByTestId('overflow').offsetLeft + overflow.offsetLeft ); }); @@ -112,6 +114,15 @@ export const Slide: Story = { canvas.getByTestId('overflow').offsetLeft ); }); + + overflow.scrollBy({ left: 1000000, behavior: 'instant' }); + + setTimeout(async () => { + await userEvent.click(forwardButton); + await waitFor(async () => { + expect(canvas.getByTestId('overflow').scrollLeft).toEqual(0); + }); + }, 300); }, };