From dcc036f65e06e1b1b2d307dc64de3516af5edb95 Mon Sep 17 00:00:00 2001 From: Skydust Date: Fri, 4 Apr 2025 08:46:42 +0200 Subject: [PATCH] first commit --- .gitignore | 1 + action.yml | 27 ++++++++ entrypoint.sh | 72 +++++++++++++++++++++ files/e2e/cypress.config.mjs | 18 ++++++ files/e2e/cypress/e2e/full-screenshot.cy.ts | 33 ++++++++++ files/e2e/cypress/support/commands.ts | 51 +++++++++++++++ files/e2e/cypress/support/e2e.ts | 1 + files/e2e/cypress/tsconfig.json | 9 +++ files/e2e/package.json | 16 +++++ 9 files changed, 228 insertions(+) create mode 100644 .gitignore create mode 100644 action.yml create mode 100644 entrypoint.sh create mode 100644 files/e2e/cypress.config.mjs create mode 100644 files/e2e/cypress/e2e/full-screenshot.cy.ts create mode 100644 files/e2e/cypress/support/commands.ts create mode 100644 files/e2e/cypress/support/e2e.ts create mode 100644 files/e2e/cypress/tsconfig.json create mode 100644 files/e2e/package.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..485dee6 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.idea diff --git a/action.yml b/action.yml new file mode 100644 index 0000000..b87c771 --- /dev/null +++ b/action.yml @@ -0,0 +1,27 @@ +name: Docker build push ! +description: A custom docker build push +author: Skydust + +# Define your inputs here. +inputs: + imageName: + description: The image name + required: true + imagePrefix: + description: The image prefix + required: false + default: ${{ gitea.server_url }}/${{ gitea.repository_owner }}/ + +runs: + using: composite + container: + image: cypress/base:22.13.1 + steps: + - name: Tests + run: | + ls + ls "$GITHUB_ACTION_PATH" + env + - name: Install node packages + uses: https://gitea.skydust.fr/actions/install-node-packages@main + \ No newline at end of file diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100644 index 0000000..d8e79aa --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,72 @@ +#!/usr/bin/env bash + +INPUT_IMAGE_NAME=$imageName +INPUT_IMAGE_PREFIX=$imagePrefix +INPUT_PUSH_IMAGE=$push +INPUT_PULL_CACHE=$pullCache +INPUT_DOCKERFILE_PATH=$path +INPUT_PLATFORM=$platform +INPUT_EXPORT_TAR=$exportTarPath +INPUT_BUILD_ARGS=$buildArgs + +set -e + +# shellcheck disable=SC2155 +export LOWERCASE_INPUT_IMAGE_PREFIX="$(echo "$INPUT_IMAGE_PREFIX" | tr '[:upper:]' '[:lower:]')" +IMAGE_NAME="$(echo "$LOWERCASE_INPUT_IMAGE_PREFIX" | sed 's/^https\?:\/\///')$INPUT_IMAGE_NAME" + +if [ -n "$DOCKER_CONFIG_BASE64" ]; then + echo "Retrieving docker config" + mkdir "$HOME/.docker/" + echo "$DOCKER_CONFIG_BASE64" | base64 -d > "$HOME/.docker/config.json" +fi; + +echo "Full image name: $IMAGE_NAME" + +if [ -z "$INPUT_IMAGE_NAME" ]; then + echo "No image name given." + exit 1 +fi; + +DOCKER_BUILD_OPTIONS=("--progress" "plain" "-t" "$IMAGE_NAME") + +if [[ -n "${INPUT_BUILD_ARGS}" ]]; then + IFS=',' read -ra allBuildArgs <<< "${INPUT_BUILD_ARGS}" + + for dockerArg in "${allBuildArgs[@]}"; do + DOCKER_BUILD_OPTIONS+=("--build-arg" "$dockerArg") + done +fi + +if [ -n "$INPUT_PLATFORM" ]; then + DOCKER_BUILD_OPTIONS+=("--platform" "$INPUT_PLATFORM" "--pull") +fi + +if [ "$INPUT_PUSH_IMAGE" = "true" ]; then + DOCKER_BUILD_OPTIONS+=("--output=type=image,name=${IMAGE_NAME},push=true,compression=zstd,compression-level=8,force-compression=true,oci-mediatypes=true") +fi + +if [ "$INPUT_PULL_CACHE" = "true" ]; then + IMAGE_CACHE_NAME="${IMAGE_NAME%%:*}:build-cache" + DOCKER_BUILD_OPTIONS+=("--cache-from" "type=registry,ref=${IMAGE_CACHE_NAME}") + DOCKER_BUILD_OPTIONS+=("--cache-to" "type=registry,image-manifest=true,oci-mediatypes=true,ref=${IMAGE_CACHE_NAME},mode=max") + echo "Using docker image cache ${IMAGE_CACHE_NAME}" +fi + +if [ -n "$INPUT_EXPORT_TAR" ]; then + DOCKER_BUILD_OPTIONS+=("--output" "type=docker,dest=$INPUT_EXPORT_TAR") +fi + +DOCKER_BUILD_OPTIONS+=("--rm") +DOCKER_BUILD_OPTIONS+=("${INPUT_DOCKERFILE_PATH}") +# shellcheck disable=SC2145 +echo "Running docker buildx with options: ${DOCKER_BUILD_OPTIONS[@]}" + +echo "Building and pushing !" +docker buildx build "${DOCKER_BUILD_OPTIONS[@]}" +echo "Cleaning up docker" +docker system prune --all --force --filter label!=ACT_IMAGE=true + +echo "imageName=${IMAGE_NAME}" >> "$GITEA_OUTPUT" + +exit 0 diff --git a/files/e2e/cypress.config.mjs b/files/e2e/cypress.config.mjs new file mode 100644 index 0000000..5a97b32 --- /dev/null +++ b/files/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/files/e2e/cypress/e2e/full-screenshot.cy.ts b/files/e2e/cypress/e2e/full-screenshot.cy.ts new file mode 100644 index 0000000..aead6df --- /dev/null +++ b/files/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/files/e2e/cypress/support/commands.ts b/files/e2e/cypress/support/commands.ts new file mode 100644 index 0000000..6887dee --- /dev/null +++ b/files/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/files/e2e/cypress/support/e2e.ts b/files/e2e/cypress/support/e2e.ts new file mode 100644 index 0000000..f887c29 --- /dev/null +++ b/files/e2e/cypress/support/e2e.ts @@ -0,0 +1 @@ +import "./commands"; diff --git a/files/e2e/cypress/tsconfig.json b/files/e2e/cypress/tsconfig.json new file mode 100644 index 0000000..05f9dd9 --- /dev/null +++ b/files/e2e/cypress/tsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "target": "es5", + "lib": ["es5", "dom"], + "sourceMap": true, + "types": ["cypress", "node"] + }, + "include": ["**/*.ts"] +} diff --git a/files/e2e/package.json b/files/e2e/package.json new file mode 100644 index 0000000..93d844b --- /dev/null +++ b/files/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" +}