From 9242ba39059342d9474c6341c1607fc76f737c5e Mon Sep 17 00:00:00 2001 From: Skydust Date: Fri, 4 Apr 2025 08:46:42 +0200 Subject: [PATCH] first commit --- .gitignore | 2 ++ Dockerfile | 18 ++++++++++ action.yml | 16 +++++++++ e2e/cypress.config.mjs | 18 ++++++++++ e2e/cypress/e2e/full-screenshot.cy.ts | 33 +++++++++++++++++ e2e/cypress/support/commands.ts | 51 +++++++++++++++++++++++++++ e2e/cypress/support/e2e.ts | 1 + e2e/cypress/tsconfig.json | 9 +++++ e2e/package.json | 16 +++++++++ entrypoint.sh | 33 +++++++++++++++++ 10 files changed, 197 insertions(+) create mode 100644 .gitignore create mode 100644 Dockerfile create mode 100644 action.yml create mode 100644 e2e/cypress.config.mjs create mode 100644 e2e/cypress/e2e/full-screenshot.cy.ts create mode 100644 e2e/cypress/support/commands.ts create mode 100644 e2e/cypress/support/e2e.ts create mode 100644 e2e/cypress/tsconfig.json create mode 100644 e2e/package.json create mode 100644 entrypoint.sh diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1f1025f --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.idea +.DS_Store \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..49b6d6b --- /dev/null +++ b/Dockerfile @@ -0,0 +1,18 @@ +FROM cypress/base:22.13.1 + +RUN npm config set @skydust:registry=https://gitea.skydust.fr/api/packages/skydust/npm/ +RUN npm install -g @skydust/toolkit@1.2.3 +RUN npm install -g corepack@latest + +RUN apt-get update +RUN apt-get install --yes firefox-esr +RUN apt-get clean + +COPY ./e2e /e2e + +RUN cd /e2e && npx cypress install + +COPY ./entrypoint.sh / +RUN chmod +x /entrypoint.sh + +ENTRYPOINT ["/entrypoint.sh"] diff --git a/action.yml b/action.yml new file mode 100644 index 0000000..a345c13 --- /dev/null +++ b/action.yml @@ -0,0 +1,16 @@ +name: Takes cypress screenshots +description: Takes cypress screenshots +author: Skydust + +# Define your inputs here. +inputs: + baseUrl: + description: The server url + required: true + +env: + GITHUB_WORKSPACE: "${{ github.workspace }}" + +runs: + using: docker + image: Dockerfile diff --git a/e2e/cypress.config.mjs b/e2e/cypress.config.mjs new file mode 100644 index 0000000..5a97b32 --- /dev/null +++ b/e2e/cypress.config.mjs @@ -0,0 +1,18 @@ +import { defineConfig } from "cypress"; +import { initPlugin } from "cypress-plugin-snapshots/plugin"; + +export default defineConfig({ + e2e: { + baseUrl: "http://127.0.0.1:5173/", + screenshotOnRunFailure: true, // Capture screenshots on test failure + setupNodeEvents(on, config) { + initPlugin(on, config); + return config; + }, + excludeSpecPattern: [ + "**/__snapshots__/*", + "**/__image_snapshots__/*" + ] + }, + screenshotsFolder: "cypress/screenshots" +}); diff --git a/e2e/cypress/e2e/full-screenshot.cy.ts b/e2e/cypress/e2e/full-screenshot.cy.ts new file mode 100644 index 0000000..aead6df --- /dev/null +++ b/e2e/cypress/e2e/full-screenshot.cy.ts @@ -0,0 +1,33 @@ +describe("full page screenshot", () => { + const takeFullPageScreenshots = () => { + cy.visit("/"); + cy.wait(500); + cy.window().toMatchImageSnapshot("first", { + threshold: 0.8 + }); + cy.wait(400); + cy.window().toMatchImageSnapshot("second", { + threshold: 0.8 + }); + }; + + it("Normal screen", () => { + cy.viewport(1280, 720); + takeFullPageScreenshots(); + }); + + it("Old puter screen", () => { + cy.viewport(800, 600); + takeFullPageScreenshots(); + }); + + it("iPhone8", () => { + cy.viewport("iphone-8"); + takeFullPageScreenshots(); + }); + + it("iPad2", () => { + cy.viewport("ipad-2"); + takeFullPageScreenshots(); + }); +}); diff --git a/e2e/cypress/support/commands.ts b/e2e/cypress/support/commands.ts new file mode 100644 index 0000000..6887dee --- /dev/null +++ b/e2e/cypress/support/commands.ts @@ -0,0 +1,51 @@ +import "cypress-plugin-snapshots/commands"; + +declare global { + namespace Cypress { + interface MatchSnapshotOptions { + /** Custom name for the snapshot */ + name?: string; + /** Save snapshot as JSON instead of plain text */ + json?: boolean; + /** Timeout in milliseconds */ + timeout?: number; + } + + interface MatchImageSnapshotOptions { + /** Custom name for the image snapshot */ + name?: string; + /** Mismatch threshold for considering images different */ + threshold?: number; + /** Type of threshold comparison */ + thresholdType?: "pixel" | "percent"; + /** Direction of the difference detection */ + diffDirection?: "horizontal" | "vertical"; + /** Allow different image sizes */ + allowSizeMismatch?: boolean; + /** Custom configuration for pixelmatch */ + customDiffConfig?: Record; + /** Path to custom snapshots directory */ + customSnapshotsDir?: string; + /** Path to custom diffs directory */ + customDiffDir?: string; + /** Capture mode */ + capture?: "viewport" | "fullPage" | "runner"; + } + + interface Chainable { + /** + * Take a text-based snapshot and compare with a baseline + * @param name - Name of the snapshot (optional) + * @param options - Snapshot options + */ + toMatchSnapshot(name?: string, options?: MatchSnapshotOptions): Chainable; + + /** + * Take an image snapshot and compare with a baseline + * @param name - Name of the snapshot (optional) + * @param options - Image snapshot options + */ + toMatchImageSnapshot(name?: string, options?: MatchImageSnapshotOptions): Chainable; + } + } +} diff --git a/e2e/cypress/support/e2e.ts b/e2e/cypress/support/e2e.ts new file mode 100644 index 0000000..f887c29 --- /dev/null +++ b/e2e/cypress/support/e2e.ts @@ -0,0 +1 @@ +import "./commands"; diff --git a/e2e/cypress/tsconfig.json b/e2e/cypress/tsconfig.json new file mode 100644 index 0000000..05f9dd9 --- /dev/null +++ b/e2e/cypress/tsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "target": "es5", + "lib": ["es5", "dom"], + "sourceMap": true, + "types": ["cypress", "node"] + }, + "include": ["**/*.ts"] +} diff --git a/e2e/package.json b/e2e/package.json new file mode 100644 index 0000000..93d844b --- /dev/null +++ b/e2e/package.json @@ -0,0 +1,16 @@ +{ + "name": "cypress-e2e", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "cy:open": "cypress open --e2e", + "cy:test": "cypress run --e2e -b firefox" + }, + "devDependencies": { + "cypress": "^14.2.1", + "cypress-plugin-snapshots": "^1.4.4", + "typescript": "~5.8.0" + }, + "packageManager": "pnpm@10.2.1+sha512.398035c7bd696d0ba0b10a688ed558285329d27ea994804a52bad9167d8e3a72bcb993f9699585d3ca25779ac64949ef422757a6c31102c12ab932e5cbe5cc92" +} diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100644 index 0000000..50aa4b7 --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash + +INPUT_BASE_URL=$baseUrl + +set -e + +CY_ACTION_PATH="/e2e" + +cd "${CY_ACTION_PATH}" + +export CYPRESS_BASE_URL="${INPUT_BASE_URL}" + +export EXPORTED_SCREENSHOTS_FOLDER="${GITHUB_WORKSPACE}/artifacts/__image_snapshots__/" +export INTERNAL_CYPRESS_SCREENSHOTS="${CY_ACTION_PATH}/cypress/e2e/__image_snapshots__/" + +log_info "Checking for screenshots to import in $(yellow)${EXPORTED_SCREENSHOTS_FOLDER}" + +if [[ -d "${EXPORTED_SCREENSHOTS_FOLDER}" ]]; then + log_info "Found the folder, importing..." + mkdir -p "${INTERNAL_CYPRESS_SCREENSHOTS}" + cp -r "${EXPORTED_SCREENSHOTS_FOLDER}"* "${INTERNAL_CYPRESS_SCREENSHOTS}" +fi + +log_info "Install cypress dependencies" +corepack enable --install-directory "/usr/local/bin/" +pnpm install + +log_info "Running cypress cy:test" + +npm run cy:test + +mkdir -p "${EXPORTED_SCREENSHOTS_FOLDER}" +cp -r "${INTERNAL_CYPRESS_SCREENSHOTS}"* "${EXPORTED_SCREENSHOTS_FOLDER}"