diff --git a/.github/workflows/pullRequests.yml b/.github/workflows/pullRequests.yml index 5c957638b7e..d32685a44e7 100644 --- a/.github/workflows/pullRequests.yml +++ b/.github/workflows/pullRequests.yml @@ -259,8 +259,8 @@ jobs: - name: Install dependencies run: yarn --immutable working-directory: ${{ github.base_ref }} - - name: Check types for Cypress tests - run: yarn cy:ts + - name: Check types for E2E tests + run: yarn e2e:ts working-directory: ${{ github.base_ref }} env: NODE_OPTIONS: '--max_old_space_size=4096' diff --git a/.github/workflows/pullRequestsCommandE2e.yml b/.github/workflows/pullRequestsCommandE2e.yml index 3f9d5474eba..7296cced8ed 100644 --- a/.github/workflows/pullRequestsCommandE2e.yml +++ b/.github/workflows/pullRequestsCommandE2e.yml @@ -33,7 +33,7 @@ jobs: with: issue-number: ${{ github.event.issue.number }} body: >- - Cypress E2E tests have been initiated (for more information, click + E2E tests have been initiated (for more information, click [here](https://github.com/webiny/webiny-js/actions/runs/${{ github.run_id }})). :sparkles: @@ -148,7 +148,6 @@ jobs: - build name: Constants - DDB outputs: - cypress-folders: ${{ steps.list-cypress-folders.outputs.cypress-folders }} pulumi-backend-url: ${{ steps.pulumi-backend-url.outputs.pulumi-backend-url }} steps: - uses: actions/setup-node@v5 @@ -162,12 +161,6 @@ jobs: run: gh pr checkout ${{ github.event.issue.number }} env: GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} - - name: List Cypress tests folders - id: list-cypress-folders - run: >- - echo "cypress-folders=$(node scripts/listCypressTestsFolders.js)" >> - $GITHUB_OUTPUT - working-directory: ${{ needs.baseBranch.outputs.base-branch }} - name: Get Pulumi backend URL id: get-pulumi-backend-url run: >- @@ -184,13 +177,10 @@ jobs: - e2e-wby-cms-ddb-constants - checkComment name: E2E (DDB) - Project setup - outputs: - cypress-config: ${{ steps.save-cypress-config.outputs.cypress-config }} environment: next env: NODE_OPTIONS: '--max_old_space_size=4096' YARN_ENABLE_IMMUTABLE_INSTALLS: false - CYPRESS_MAILOSAUR_API_KEY: ${{ secrets.CYPRESS_MAILOSAUR_API_KEY }} PULUMI_CONFIG_PASSPHRASE: ${{ secrets.PULUMI_CONFIG_PASSPHRASE }} PULUMI_SECRETS_PROVIDER: ${{ secrets.PULUMI_SECRETS_PROVIDER }} WEBINY_PULUMI_BACKEND: ${{ needs.e2e-wby-cms-ddb-constants.outputs.pulumi-backend-url }} @@ -313,23 +303,24 @@ jobs: gh api repos/${{ github.repository }}/issues/comments/$COMMENT_ID -X PATCH --field body=@/tmp/comment.txt - - name: Create Cypress config - run: yarn setup-cypress --projectFolder ../new-webiny-project - working-directory: ${{ needs.baseBranch.outputs.base-branch }} - - name: Save Cypress config - id: save-cypress-config - run: >- - echo "cypress-config=$(cat cypress-tests/cypress.config.ts | tr -d - '\t\n\r')" >> $GITHUB_OUTPUT - working-directory: ${{ needs.baseBranch.outputs.base-branch }} - - name: Install Cypress binary - run: cd cypress-tests && yarn cypress install - working-directory: ${{ needs.baseBranch.outputs.base-branch }} - - name: Cypress - run installation wizard test - run: >- - yarn cy:run --browser chrome --spec - "cypress/e2e/adminInstallation/**/*.cy.js" + - name: E2E - run installation wizard test working-directory: ${{ needs.baseBranch.outputs.base-branch }} + env: + E2E_ADMIN_URL: ${{ steps.admin-url.outputs.admin-url }} + E2E_INSTALLATION: '1' + E2E_TELEMETRY_DISABLED: '1' + run: |- + yarn workspace e2e-tests playwright install --with-deps chromium + yarn e2e --tag installation + - name: E2E - upload installation test results + if: failure() + uses: actions/upload-artifact@v6 + with: + name: e2e-results-ddb + retention-days: 7 + if-no-files-found: ignore + include-hidden-files: true + path: ${{ needs.baseBranch.outputs.base-branch }}/e2e/.e2e runs-on: ubuntu-latest permissions: id-token: write @@ -340,7 +331,6 @@ jobs: - build name: Constants - DDB-OS outputs: - cypress-folders: ${{ steps.list-cypress-folders.outputs.cypress-folders }} pulumi-backend-url: ${{ steps.pulumi-backend-url.outputs.pulumi-backend-url }} steps: - uses: actions/setup-node@v5 @@ -354,12 +344,6 @@ jobs: run: gh pr checkout ${{ github.event.issue.number }} env: GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} - - name: List Cypress tests folders - id: list-cypress-folders - run: >- - echo "cypress-folders=$(node scripts/listCypressTestsFolders.js)" >> - $GITHUB_OUTPUT - working-directory: ${{ needs.baseBranch.outputs.base-branch }} - name: Get Pulumi backend URL id: get-pulumi-backend-url run: >- @@ -376,13 +360,10 @@ jobs: - e2e-wby-cms-ddb-os-constants - checkComment name: E2E (DDB-OS) - Project setup - outputs: - cypress-config: ${{ steps.save-cypress-config.outputs.cypress-config }} environment: next env: NODE_OPTIONS: '--max_old_space_size=4096' YARN_ENABLE_IMMUTABLE_INSTALLS: false - CYPRESS_MAILOSAUR_API_KEY: ${{ secrets.CYPRESS_MAILOSAUR_API_KEY }} PULUMI_CONFIG_PASSPHRASE: ${{ secrets.PULUMI_CONFIG_PASSPHRASE }} PULUMI_SECRETS_PROVIDER: ${{ secrets.PULUMI_SECRETS_PROVIDER }} WEBINY_PULUMI_BACKEND: ${{ needs.e2e-wby-cms-ddb-os-constants.outputs.pulumi-backend-url }} @@ -526,23 +507,24 @@ jobs: gh api repos/${{ github.repository }}/issues/comments/$COMMENT_ID -X PATCH --field body=@/tmp/comment.txt - - name: Create Cypress config - run: yarn setup-cypress --projectFolder ../new-webiny-project - working-directory: ${{ needs.baseBranch.outputs.base-branch }} - - name: Save Cypress config - id: save-cypress-config - run: >- - echo "cypress-config=$(cat cypress-tests/cypress.config.ts | tr -d - '\t\n\r')" >> $GITHUB_OUTPUT - working-directory: ${{ needs.baseBranch.outputs.base-branch }} - - name: Install Cypress binary - run: cd cypress-tests && yarn cypress install - working-directory: ${{ needs.baseBranch.outputs.base-branch }} - - name: Cypress - run installation wizard test - run: >- - yarn cy:run --browser chrome --spec - "cypress/e2e/adminInstallation/**/*.cy.js" + - name: E2E - run installation wizard test working-directory: ${{ needs.baseBranch.outputs.base-branch }} + env: + E2E_ADMIN_URL: ${{ steps.admin-url.outputs.admin-url }} + E2E_INSTALLATION: '1' + E2E_TELEMETRY_DISABLED: '1' + run: |- + yarn workspace e2e-tests playwright install --with-deps chromium + yarn e2e --tag installation + - name: E2E - upload installation test results + if: failure() + uses: actions/upload-artifact@v6 + with: + name: e2e-results-ddb-os + retention-days: 7 + if-no-files-found: ignore + include-hidden-files: true + path: ${{ needs.baseBranch.outputs.base-branch }}/e2e/.e2e runs-on: ubuntu-latest permissions: id-token: write diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index 7260f7b6312..14f8f81ce18 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -159,8 +159,8 @@ jobs: - name: Install dependencies run: yarn --immutable working-directory: v6 - - name: Check types for Cypress tests - run: yarn cy:ts + - name: Check types for E2E tests + run: yarn e2e:ts working-directory: v6 env: NODE_OPTIONS: '--max_old_space_size=4096' @@ -494,18 +494,12 @@ jobs: needs: - build outputs: - cypress-folders: ${{ steps.list-cypress-folders.outputs.cypress-folders }} pulumi-backend-url: ${{ steps.pulumi-backend-url.outputs.pulumi-backend-url }} steps: - uses: actions/setup-node@v5 with: node-version: 24 - uses: actions/checkout@v5 - - name: List Cypress tests folders - id: list-cypress-folders - run: >- - echo "cypress-folders=$(node scripts/listCypressTestsFolders.js)" >> - $GITHUB_OUTPUT - name: Get Pulumi backend URL id: get-pulumi-backend-url run: >- @@ -522,13 +516,10 @@ jobs: - e2eTests-ddb-constants runs-on: webiny-build-packages name: E2E (DDB) - Project setup - outputs: - cypress-config: ${{ steps.save-cypress-config.outputs.cypress-config }} environment: next env: NODE_OPTIONS: '--max_old_space_size=4096' YARN_ENABLE_IMMUTABLE_INSTALLS: 'false' - CYPRESS_MAILOSAUR_API_KEY: ${{ secrets.CYPRESS_MAILOSAUR_API_KEY }} PULUMI_CONFIG_PASSPHRASE: ${{ secrets.PULUMI_CONFIG_PASSPHRASE }} PULUMI_SECRETS_PROVIDER: ${{ secrets.PULUMI_SECRETS_PROVIDER }} WEBINY_PULUMI_BACKEND: ${{ needs.e2eTests-ddb-constants.outputs.pulumi-backend-url }} @@ -626,23 +617,30 @@ jobs: - name: Deploy Admin Area working-directory: new-webiny-project run: yarn webiny deploy admin --env dev - - name: Create Cypress config - run: yarn setup-cypress --projectFolder ../new-webiny-project - working-directory: v6 - - name: Save Cypress config - id: save-cypress-config - run: >- - echo "cypress-config=$(cat cypress-tests/cypress.config.ts | tr -d - '\t\n\r')" >> $GITHUB_OUTPUT - working-directory: v6 - - name: Install Cypress binary - run: cd cypress-tests && yarn cypress install - working-directory: v6 - - name: Cypress - run installation wizard test + - name: Extract admin app URL + id: admin-url + working-directory: new-webiny-project run: >- - yarn cy:run --browser chrome --spec - "cypress/e2e/adminInstallation/**/*.cy.js" + echo "admin-url=$(yarn webiny output admin --env dev --json + 2>/dev/null | jq -r '.appUrl // empty')" >> $GITHUB_OUTPUT + - name: E2E - run installation wizard test working-directory: v6 + env: + E2E_ADMIN_URL: ${{ steps.admin-url.outputs.admin-url }} + E2E_INSTALLATION: '1' + E2E_TELEMETRY_DISABLED: '1' + run: |- + yarn workspace e2e-tests playwright install --with-deps chromium + yarn e2e --tag installation + - name: E2E - upload installation test results + if: failure() + uses: actions/upload-artifact@v6 + with: + name: e2e-results-ddb + retention-days: 7 + if-no-files-found: ignore + include-hidden-files: true + path: v6/e2e/.e2e permissions: id-token: write e2eTests-ddb-os-constants: @@ -650,18 +648,12 @@ jobs: needs: - build outputs: - cypress-folders: ${{ steps.list-cypress-folders.outputs.cypress-folders }} pulumi-backend-url: ${{ steps.pulumi-backend-url.outputs.pulumi-backend-url }} steps: - uses: actions/setup-node@v5 with: node-version: 24 - uses: actions/checkout@v5 - - name: List Cypress tests folders - id: list-cypress-folders - run: >- - echo "cypress-folders=$(node scripts/listCypressTestsFolders.js)" >> - $GITHUB_OUTPUT - name: Get Pulumi backend URL id: get-pulumi-backend-url run: >- @@ -678,13 +670,10 @@ jobs: - e2eTests-ddb-os-constants runs-on: webiny-build-packages name: E2E (DDB+OS) - Project setup - outputs: - cypress-config: ${{ steps.save-cypress-config.outputs.cypress-config }} environment: next env: NODE_OPTIONS: '--max_old_space_size=4096' YARN_ENABLE_IMMUTABLE_INSTALLS: 'false' - CYPRESS_MAILOSAUR_API_KEY: ${{ secrets.CYPRESS_MAILOSAUR_API_KEY }} PULUMI_CONFIG_PASSPHRASE: ${{ secrets.PULUMI_CONFIG_PASSPHRASE }} PULUMI_SECRETS_PROVIDER: ${{ secrets.PULUMI_SECRETS_PROVIDER }} WEBINY_PULUMI_BACKEND: ${{ needs.e2eTests-ddb-os-constants.outputs.pulumi-backend-url }} @@ -803,22 +792,29 @@ jobs: && echo "$OUTPUT" | jq -e '.databaseSetup == "ddb+os"' || (echo "ERROR: Expected databaseSetup to be 'ddb+os' but got a different value" && exit 1) - - name: Create Cypress config - run: yarn setup-cypress --projectFolder ../new-webiny-project - working-directory: v6 - - name: Save Cypress config - id: save-cypress-config - run: >- - echo "cypress-config=$(cat cypress-tests/cypress.config.ts | tr -d - '\t\n\r')" >> $GITHUB_OUTPUT - working-directory: v6 - - name: Install Cypress binary - run: cd cypress-tests && yarn cypress install - working-directory: v6 - - name: Cypress - run installation wizard test + - name: Extract admin app URL + id: admin-url + working-directory: new-webiny-project run: >- - yarn cy:run --browser chrome --spec - "cypress/e2e/adminInstallation/**/*.cy.js" + echo "admin-url=$(yarn webiny output admin --env dev --json + 2>/dev/null | jq -r '.appUrl // empty')" >> $GITHUB_OUTPUT + - name: E2E - run installation wizard test working-directory: v6 + env: + E2E_ADMIN_URL: ${{ steps.admin-url.outputs.admin-url }} + E2E_INSTALLATION: '1' + E2E_TELEMETRY_DISABLED: '1' + run: |- + yarn workspace e2e-tests playwright install --with-deps chromium + yarn e2e --tag installation + - name: E2E - upload installation test results + if: failure() + uses: actions/upload-artifact@v6 + with: + name: e2e-results-ddb-os + retention-days: 7 + if-no-files-found: ignore + include-hidden-files: true + path: v6/e2e/.e2e permissions: id-token: write diff --git a/.github/workflows/v5_PullRequestsCommandCypress.yml b/.github/workflows/v5_PullRequestsCommandCypress.yml deleted file mode 100644 index bf5b39a6763..00000000000 --- a/.github/workflows/v5_PullRequestsCommandCypress.yml +++ /dev/null @@ -1,600 +0,0 @@ -# This file was automatically generated by github-actions-wac. -# DO NOT MODIFY IT BY HAND. Instead, modify the source *.wac.ts file(s) -# and run "github-actions-wac build" (or "ghawac build") to regenerate this file. -# For more information, run "github-actions-wac --help". -name: (v5) Pull Requests Command - Cypress -'on': issue_comment -env: - NODE_OPTIONS: '--max_old_space_size=4096' - AWS_REGION: eu-central-1 -jobs: - checkComment: - name: Check comment for /v5_cypress - if: ${{ github.event.issue.pull_request }} - steps: - - uses: actions/setup-node@v5 - with: - node-version: 24 - - name: Check for Command - id: command - uses: xt0rted/slash-command-action@v2 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - command: v5_cypress - reaction: 'true' - reaction-type: eyes - allow-edits: 'false' - permission-level: write - - name: Create comment - uses: peter-evans/create-or-update-comment@v2 - with: - issue-number: ${{ github.event.issue.number }} - body: >- - Cypress E2E tests have been initiated (for more information, click - [here](https://github.com/webiny/webiny-js/actions/runs/${{ - github.run_id }})). :sparkles: - runs-on: ubuntu-latest - env: - NODE_OPTIONS: '--max_old_space_size=4096' - YARN_ENABLE_IMMUTABLE_INSTALLS: false - baseBranch: - needs: checkComment - name: Get base branch - outputs: - base-branch: ${{ steps.base-branch.outputs.base-branch }} - steps: - - uses: actions/setup-node@v5 - with: - node-version: 24 - - uses: actions/checkout@v5 - - name: Get base branch - id: base-branch - env: - GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} - run: >- - echo "base-branch=$(gh pr view ${{ github.event.issue.number }} --json - baseRefName -q .baseRefName)" >> $GITHUB_OUTPUT - runs-on: ubuntu-latest - env: - NODE_OPTIONS: '--max_old_space_size=4096' - YARN_ENABLE_IMMUTABLE_INSTALLS: false - constants: - needs: baseBranch - name: Create constants - outputs: - global-cache-key: ${{ steps.global-cache-key.outputs.global-cache-key }} - run-cache-key: ${{ steps.run-cache-key.outputs.run-cache-key }} - steps: - - uses: actions/setup-node@v5 - with: - node-version: 24 - - name: Create global cache key - id: global-cache-key - run: >- - echo "global-cache-key=${{ needs.baseBranch.outputs.base-branch }}-${{ - runner.os }}-$(/bin/date -u "+%m%d")-${{ vars.RANDOM_CACHE_KEY_SUFFIX - }}" >> $GITHUB_OUTPUT - - name: Create workflow run cache key - id: run-cache-key - run: >- - echo "run-cache-key=${{ github.run_id }}-${{ github.run_attempt }}-${{ - vars.RANDOM_CACHE_KEY_SUFFIX }}" >> $GITHUB_OUTPUT - runs-on: ubuntu-latest - env: - NODE_OPTIONS: '--max_old_space_size=4096' - YARN_ENABLE_IMMUTABLE_INSTALLS: false - build: - name: Build - needs: - - baseBranch - - constants - runs-on: webiny-build-packages - steps: - - uses: actions/setup-node@v5 - with: - node-version: 24 - - uses: actions/checkout@v5 - with: - path: ${{ needs.baseBranch.outputs.base-branch }} - - name: Checkout Pull Request - working-directory: ${{ needs.baseBranch.outputs.base-branch }} - run: gh pr checkout ${{ github.event.issue.number }} - env: - GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} - - uses: actions/cache@v5 - with: - path: ${{ needs.baseBranch.outputs.base-branch }}/.yarn/cache - key: yarn-${{ runner.os }}-${{ hashFiles('**/yarn.lock') }} - - uses: actions/cache@v5 - with: - path: ${{ needs.baseBranch.outputs.base-branch }}/.webiny/cached-packages - key: ${{ needs.constants.outputs.global-cache-key }} - - name: Install dependencies - run: yarn --immutable - working-directory: ${{ needs.baseBranch.outputs.base-branch }} - - name: Build packages - run: yarn build - working-directory: ${{ needs.baseBranch.outputs.base-branch }} - - uses: actions/cache@v5 - with: - path: ${{ needs.baseBranch.outputs.base-branch }}/.webiny/cached-packages - key: ${{ needs.constants.outputs.run-cache-key }} - env: - NODE_OPTIONS: '--max_old_space_size=4096' - YARN_ENABLE_IMMUTABLE_INSTALLS: false - e2e-wby-cms-ddb-constants: - needs: - - baseBranch - - constants - - build - name: Constants - DDB - outputs: - cypress-folders: ${{ steps.list-cypress-folders.outputs.cypress-folders }} - pulumi-backend-url: ${{ steps.pulumi-backend-url.outputs.pulumi-backend-url }} - steps: - - uses: actions/setup-node@v5 - with: - node-version: 24 - - uses: actions/checkout@v5 - with: - path: ${{ needs.baseBranch.outputs.base-branch }} - - name: Checkout Pull Request - working-directory: ${{ needs.baseBranch.outputs.base-branch }} - run: gh pr checkout ${{ github.event.issue.number }} - env: - GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} - - name: List Cypress tests folders - id: list-cypress-folders - run: >- - echo "cypress-folders=$(node scripts/listCypressTestsFolders.js)" >> - $GITHUB_OUTPUT - working-directory: ${{ needs.baseBranch.outputs.base-branch }} - - name: Get Pulumi backend URL - id: get-pulumi-backend-url - run: >- - echo "pulumi-backend-url=${{ secrets.WEBINY_PULUMI_BACKEND }}${{ - github.run_id }}_ddb" >> $GITHUB_OUTPUT - runs-on: ubuntu-latest - env: - NODE_OPTIONS: '--max_old_space_size=4096' - YARN_ENABLE_IMMUTABLE_INSTALLS: false - e2e-wby-cms-ddb-project-setup: - needs: - - baseBranch - - constants - - e2e-wby-cms-ddb-constants - name: E2E (DDB) - Project setup - outputs: - cypress-config: ${{ steps.save-cypress-config.outputs.cypress-config }} - environment: next - env: - NODE_OPTIONS: '--max_old_space_size=4096' - YARN_ENABLE_IMMUTABLE_INSTALLS: false - CYPRESS_MAILOSAUR_API_KEY: ${{ secrets.CYPRESS_MAILOSAUR_API_KEY }} - PULUMI_CONFIG_PASSPHRASE: ${{ secrets.PULUMI_CONFIG_PASSPHRASE }} - PULUMI_SECRETS_PROVIDER: ${{ secrets.PULUMI_SECRETS_PROVIDER }} - WEBINY_PULUMI_BACKEND: ${{ needs.e2e-wby-cms-ddb-constants.outputs.pulumi-backend-url }} - steps: - - uses: actions/setup-node@v5 - with: - node-version: 24 - - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@v6.0.0 - with: - role-to-assume: arn:aws:iam::726952677045:role/GitHubActionsWebinyJs - aws-region: eu-central-1 - - uses: actions/checkout@v5 - with: - path: ${{ needs.baseBranch.outputs.base-branch }} - - name: Checkout Pull Request - working-directory: ${{ needs.baseBranch.outputs.base-branch }} - run: gh pr checkout ${{ github.event.issue.number }} - env: - GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} - - uses: actions/cache@v5 - with: - path: ${{ needs.baseBranch.outputs.base-branch }}/.yarn/cache - key: yarn-${{ runner.os }}-${{ hashFiles('**/yarn.lock') }} - - uses: actions/cache@v5 - with: - path: ${{ needs.baseBranch.outputs.base-branch }}/.webiny/cached-packages - key: ${{ needs.constants.outputs.run-cache-key }} - - name: Install dependencies - run: yarn --immutable - working-directory: ${{ needs.baseBranch.outputs.base-branch }} - - name: Build packages - run: yarn build - working-directory: ${{ needs.baseBranch.outputs.base-branch }} - - name: Start Verdaccio local server - working-directory: ${{ needs.baseBranch.outputs.base-branch }} - run: >- - yarn add pm2 verdaccio && npx pm2 start verdaccio -- -c - .verdaccio.yaml - - name: Configure NPM to use local registry - run: npm config set registry http://localhost:4873 - - name: Set git email - run: git config --global user.email "webiny-bot@webiny.com" - - name: Set git username - run: git config --global user.name "webiny-bot" - - name: Create ".npmrc" file in the project root, with a dummy auth token - working-directory: ${{ needs.baseBranch.outputs.base-branch }} - run: echo '//localhost:4873/:_authToken="dummy-auth-token"' > .npmrc - - name: Version and publish to Verdaccio - working-directory: ${{ needs.baseBranch.outputs.base-branch }} - run: yarn release --type=verdaccio - - name: Create verdaccio-files artifact - uses: actions/upload-artifact@v6 - with: - name: verdaccio-files-ddb - retention-days: 1 - include-hidden-files: true - path: |- - ${{ needs.baseBranch.outputs.base-branch }}/.verdaccio/ - ${{ needs.baseBranch.outputs.base-branch }}/.verdaccio.yaml - - name: Disable Webiny telemetry - run: > - mkdir ~/.webiny && echo '{ "id": "ci", "telemetry": false }' > - ~/.webiny/config - - name: Create a new Webiny project - run: > - npx create-webiny-project@local-npm new-webiny-project --tag local-npm - --no-interactive --assign-to-yarnrc - '{"npmRegistryServer":"http://localhost:4873","unsafeHttpWhitelist":["localhost"]}' - --template-options '{"region":"${{ env.AWS_REGION - }}","storageOps":"ddb"}' - - name: Print CLI version - working-directory: new-webiny-project - run: yarn webiny --version - - name: Create project-files artifact - uses: actions/upload-artifact@v6 - with: - name: project-files-ddb - retention-days: 1 - include-hidden-files: true - path: |- - new-webiny-project/ - !new-webiny-project/node_modules/**/* - !new-webiny-project/**/node_modules/**/* - !new-webiny-project/.yarn/cache/**/* - - name: Deploy Core - working-directory: new-webiny-project - run: yarn webiny deploy core --env dev - - name: Deploy API - working-directory: new-webiny-project - run: yarn webiny deploy api --env dev - - name: Deploy Admin Area - working-directory: new-webiny-project - run: yarn webiny deploy admin --env dev - - name: Deploy Website - working-directory: new-webiny-project - run: yarn webiny deploy website --env dev - - name: Create Cypress config - run: yarn setup-cypress --projectFolder ../new-webiny-project - working-directory: ${{ needs.baseBranch.outputs.base-branch }} - - name: Save Cypress config - id: save-cypress-config - run: >- - echo "cypress-config=$(cat cypress-tests/cypress.config.ts | tr -d - '\t\n\r')" >> $GITHUB_OUTPUT - working-directory: ${{ needs.baseBranch.outputs.base-branch }} - - name: Install Cypress binary - run: cd cypress-tests && yarn cypress install - working-directory: ${{ needs.baseBranch.outputs.base-branch }} - - name: Cypress - run installation wizard test - run: >- - yarn cy:run --browser chrome --spec - "cypress/e2e/adminInstallation/**/*.cy.js" - working-directory: ${{ needs.baseBranch.outputs.base-branch }} - runs-on: ubuntu-latest - permissions: - id-token: write - e2e-wby-cms-ddb-cypress-tests: - name: >- - ${{ matrix.cypress-folder }} (ddb, ${{ matrix.os }}, Node v${{ matrix.node - }}) - needs: - - baseBranch - - constants - - e2e-wby-cms-ddb-constants - - e2e-wby-cms-ddb-project-setup - strategy: - fail-fast: false - matrix: - os: - - ubuntu-latest - node: - - 24 - cypress-folder: >- - ${{ fromJson(needs.e2e-wby-cms-ddb-constants.outputs.cypress-folders) - }} - environment: next - env: - NODE_OPTIONS: '--max_old_space_size=4096' - YARN_ENABLE_IMMUTABLE_INSTALLS: false - CYPRESS_MAILOSAUR_API_KEY: ${{ secrets.CYPRESS_MAILOSAUR_API_KEY }} - PULUMI_CONFIG_PASSPHRASE: ${{ secrets.PULUMI_CONFIG_PASSPHRASE }} - PULUMI_SECRETS_PROVIDER: ${{ secrets.PULUMI_SECRETS_PROVIDER }} - WEBINY_PULUMI_BACKEND: ${{ needs.e2e-wby-cms-ddb-constants.outputs.pulumi-backend-url }} - steps: - - uses: actions/setup-node@v5 - with: - node-version: 24 - - uses: actions/checkout@v5 - with: - path: ${{ needs.baseBranch.outputs.base-branch }} - - name: Checkout Pull Request - working-directory: ${{ needs.baseBranch.outputs.base-branch }} - run: gh pr checkout ${{ github.event.issue.number }} - env: - GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} - - uses: actions/cache@v5 - with: - path: ${{ needs.baseBranch.outputs.base-branch }}/.yarn/cache - key: yarn-${{ runner.os }}-${{ hashFiles('**/yarn.lock') }} - - uses: actions/cache@v5 - with: - path: ${{ needs.baseBranch.outputs.base-branch }}/.webiny/cached-packages - key: ${{ needs.constants.outputs.run-cache-key }} - - name: Install dependencies - run: yarn --immutable - working-directory: ${{ needs.baseBranch.outputs.base-branch }} - - name: Build packages - run: yarn build - working-directory: ${{ needs.baseBranch.outputs.base-branch }} - - name: Set up Cypress config - working-directory: ${{ needs.baseBranch.outputs.base-branch }} - run: >- - echo '${{ needs.e2e-wby-cms-ddb-project-setup.outputs.cypress-config - }}' > cypress-tests/cypress.config.ts - - name: Install Cypress binary - working-directory: ${{ needs.baseBranch.outputs.base-branch }} - run: cd cypress-tests && yarn cypress install - - name: Cypress - run "${{ matrix.cypress-folder }}" tests - timeout-minutes: 40 - working-directory: ${{ needs.baseBranch.outputs.base-branch }} - run: yarn cy:run --browser chrome --spec "${{ matrix.cypress-folder }}" - runs-on: ubuntu-latest - e2e-wby-cms-ddb-os-constants: - needs: - - baseBranch - - constants - - build - name: Constants - DDB-OS - outputs: - cypress-folders: ${{ steps.list-cypress-folders.outputs.cypress-folders }} - pulumi-backend-url: ${{ steps.pulumi-backend-url.outputs.pulumi-backend-url }} - steps: - - uses: actions/setup-node@v5 - with: - node-version: 24 - - uses: actions/checkout@v5 - with: - path: ${{ needs.baseBranch.outputs.base-branch }} - - name: Checkout Pull Request - working-directory: ${{ needs.baseBranch.outputs.base-branch }} - run: gh pr checkout ${{ github.event.issue.number }} - env: - GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} - - name: List Cypress tests folders - id: list-cypress-folders - run: >- - echo "cypress-folders=$(node scripts/listCypressTestsFolders.js)" >> - $GITHUB_OUTPUT - working-directory: ${{ needs.baseBranch.outputs.base-branch }} - - name: Get Pulumi backend URL - id: get-pulumi-backend-url - run: >- - echo "pulumi-backend-url=${{ secrets.WEBINY_PULUMI_BACKEND }}${{ - github.run_id }}_ddb-os" >> $GITHUB_OUTPUT - runs-on: ubuntu-latest - env: - NODE_OPTIONS: '--max_old_space_size=4096' - YARN_ENABLE_IMMUTABLE_INSTALLS: false - e2e-wby-cms-ddb-os-project-setup: - needs: - - baseBranch - - constants - - e2e-wby-cms-ddb-os-constants - name: E2E (DDB-OS) - Project setup - outputs: - cypress-config: ${{ steps.save-cypress-config.outputs.cypress-config }} - environment: next - env: - NODE_OPTIONS: '--max_old_space_size=4096' - YARN_ENABLE_IMMUTABLE_INSTALLS: false - CYPRESS_MAILOSAUR_API_KEY: ${{ secrets.CYPRESS_MAILOSAUR_API_KEY }} - PULUMI_CONFIG_PASSPHRASE: ${{ secrets.PULUMI_CONFIG_PASSPHRASE }} - PULUMI_SECRETS_PROVIDER: ${{ secrets.PULUMI_SECRETS_PROVIDER }} - WEBINY_PULUMI_BACKEND: ${{ needs.e2e-wby-cms-ddb-os-constants.outputs.pulumi-backend-url }} - AWS_OPENSEARCH_DOMAIN_NAME: ${{ secrets.V5_OPENSEARCH_DOMAIN_NAME }} - OPENSEARCH_ENDPOINT: ${{ secrets.V5_OPENSEARCH_ENDPOINT }} - OPENSEARCH_USERNAME: ${{ secrets.V5_OPENSEARCH_USERNAME }} - OPENSEARCH_PASSWORD: ${{ secrets.V5_OPENSEARCH_PASSWORD }} - OPENSEARCH_INDEX_PREFIX: ${{ github.run_id }}_ - steps: - - uses: actions/setup-node@v5 - with: - node-version: 24 - - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@v6.0.0 - with: - role-to-assume: arn:aws:iam::726952677045:role/GitHubActionsWebinyJs - aws-region: eu-central-1 - - uses: actions/checkout@v5 - with: - path: ${{ needs.baseBranch.outputs.base-branch }} - - name: Checkout Pull Request - working-directory: ${{ needs.baseBranch.outputs.base-branch }} - run: gh pr checkout ${{ github.event.issue.number }} - env: - GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} - - uses: actions/cache@v5 - with: - path: ${{ needs.baseBranch.outputs.base-branch }}/.yarn/cache - key: yarn-${{ runner.os }}-${{ hashFiles('**/yarn.lock') }} - - uses: actions/cache@v5 - with: - path: ${{ needs.baseBranch.outputs.base-branch }}/.webiny/cached-packages - key: ${{ needs.constants.outputs.run-cache-key }} - - name: Install dependencies - run: yarn --immutable - working-directory: ${{ needs.baseBranch.outputs.base-branch }} - - name: Build packages - run: yarn build - working-directory: ${{ needs.baseBranch.outputs.base-branch }} - - name: Start Verdaccio local server - working-directory: ${{ needs.baseBranch.outputs.base-branch }} - run: >- - yarn add pm2 verdaccio && npx pm2 start verdaccio -- -c - .verdaccio.yaml - - name: Configure NPM to use local registry - run: npm config set registry http://localhost:4873 - - name: Set git email - run: git config --global user.email "webiny-bot@webiny.com" - - name: Set git username - run: git config --global user.name "webiny-bot" - - name: Create ".npmrc" file in the project root, with a dummy auth token - working-directory: ${{ needs.baseBranch.outputs.base-branch }} - run: echo '//localhost:4873/:_authToken="dummy-auth-token"' > .npmrc - - name: Version and publish to Verdaccio - working-directory: ${{ needs.baseBranch.outputs.base-branch }} - run: yarn release --type=verdaccio - - name: Create verdaccio-files artifact - uses: actions/upload-artifact@v6 - with: - name: verdaccio-files-ddb-os - retention-days: 1 - include-hidden-files: true - path: |- - ${{ needs.baseBranch.outputs.base-branch }}/.verdaccio/ - ${{ needs.baseBranch.outputs.base-branch }}/.verdaccio.yaml - - name: Disable Webiny telemetry - run: > - mkdir ~/.webiny && echo '{ "id": "ci", "telemetry": false }' > - ~/.webiny/config - - name: Create a new Webiny project - run: > - npx create-webiny-project@local-npm new-webiny-project --tag local-npm - --no-interactive --assign-to-yarnrc - '{"npmRegistryServer":"http://localhost:4873","unsafeHttpWhitelist":["localhost"]}' - --template-options '{"region":"${{ env.AWS_REGION - }}","storageOps":"ddb-os"}' - - name: Print CLI version - working-directory: new-webiny-project - run: yarn webiny --version - - name: Create project-files artifact - uses: actions/upload-artifact@v6 - with: - name: project-files-ddb-os - retention-days: 1 - include-hidden-files: true - path: |- - new-webiny-project/ - !new-webiny-project/node_modules/**/* - !new-webiny-project/**/node_modules/**/* - !new-webiny-project/.yarn/cache/**/* - - name: Deploy Core - working-directory: new-webiny-project - run: yarn webiny deploy core --env dev - - name: Deploy API - working-directory: new-webiny-project - run: yarn webiny deploy api --env dev - - name: Deploy Admin Area - working-directory: new-webiny-project - run: yarn webiny deploy admin --env dev - - name: Deploy Website - working-directory: new-webiny-project - run: yarn webiny deploy website --env dev - - name: Create Cypress config - run: yarn setup-cypress --projectFolder ../new-webiny-project - working-directory: ${{ needs.baseBranch.outputs.base-branch }} - - name: Save Cypress config - id: save-cypress-config - run: >- - echo "cypress-config=$(cat cypress-tests/cypress.config.ts | tr -d - '\t\n\r')" >> $GITHUB_OUTPUT - working-directory: ${{ needs.baseBranch.outputs.base-branch }} - - name: Install Cypress binary - run: cd cypress-tests && yarn cypress install - working-directory: ${{ needs.baseBranch.outputs.base-branch }} - - name: Cypress - run installation wizard test - run: >- - yarn cy:run --browser chrome --spec - "cypress/e2e/adminInstallation/**/*.cy.js" - working-directory: ${{ needs.baseBranch.outputs.base-branch }} - runs-on: ubuntu-latest - permissions: - id-token: write - e2e-wby-cms-ddb-os-cypress-tests: - name: >- - ${{ matrix.cypress-folder }} (ddb-os, ${{ matrix.os }}, Node v${{ - matrix.node }}) - needs: - - baseBranch - - constants - - e2e-wby-cms-ddb-os-constants - - e2e-wby-cms-ddb-os-project-setup - strategy: - fail-fast: false - matrix: - os: - - ubuntu-latest - node: - - 24 - cypress-folder: >- - ${{ - fromJson(needs.e2e-wby-cms-ddb-os-constants.outputs.cypress-folders) - }} - environment: next - env: - NODE_OPTIONS: '--max_old_space_size=4096' - YARN_ENABLE_IMMUTABLE_INSTALLS: false - CYPRESS_MAILOSAUR_API_KEY: ${{ secrets.CYPRESS_MAILOSAUR_API_KEY }} - PULUMI_CONFIG_PASSPHRASE: ${{ secrets.PULUMI_CONFIG_PASSPHRASE }} - PULUMI_SECRETS_PROVIDER: ${{ secrets.PULUMI_SECRETS_PROVIDER }} - WEBINY_PULUMI_BACKEND: ${{ needs.e2e-wby-cms-ddb-os-constants.outputs.pulumi-backend-url }} - AWS_OPENSEARCH_DOMAIN_NAME: ${{ secrets.V5_OPENSEARCH_DOMAIN_NAME }} - OPENSEARCH_ENDPOINT: ${{ secrets.V5_OPENSEARCH_ENDPOINT }} - OPENSEARCH_USERNAME: ${{ secrets.V5_OPENSEARCH_USERNAME }} - OPENSEARCH_PASSWORD: ${{ secrets.V5_OPENSEARCH_PASSWORD }} - OPENSEARCH_INDEX_PREFIX: ${{ github.run_id }}_ - steps: - - uses: actions/setup-node@v5 - with: - node-version: 24 - - uses: actions/checkout@v5 - with: - path: ${{ needs.baseBranch.outputs.base-branch }} - - name: Checkout Pull Request - working-directory: ${{ needs.baseBranch.outputs.base-branch }} - run: gh pr checkout ${{ github.event.issue.number }} - env: - GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} - - uses: actions/cache@v5 - with: - path: ${{ needs.baseBranch.outputs.base-branch }}/.yarn/cache - key: yarn-${{ runner.os }}-${{ hashFiles('**/yarn.lock') }} - - uses: actions/cache@v5 - with: - path: ${{ needs.baseBranch.outputs.base-branch }}/.webiny/cached-packages - key: ${{ needs.constants.outputs.run-cache-key }} - - name: Install dependencies - run: yarn --immutable - working-directory: ${{ needs.baseBranch.outputs.base-branch }} - - name: Build packages - run: yarn build - working-directory: ${{ needs.baseBranch.outputs.base-branch }} - - name: Set up Cypress config - working-directory: ${{ needs.baseBranch.outputs.base-branch }} - run: >- - echo '${{ - needs.e2e-wby-cms-ddb-os-project-setup.outputs.cypress-config }}' > - cypress-tests/cypress.config.ts - - name: Install Cypress binary - working-directory: ${{ needs.baseBranch.outputs.base-branch }} - run: cd cypress-tests && yarn cypress install - - name: Cypress - run "${{ matrix.cypress-folder }}" tests - timeout-minutes: 40 - working-directory: ${{ needs.baseBranch.outputs.base-branch }} - run: yarn cy:run --browser chrome --spec "${{ matrix.cypress-folder }}" - runs-on: ubuntu-latest diff --git a/.github/workflows/wac/pullRequests.wac.ts b/.github/workflows/wac/pullRequests.wac.ts index ac47cf5fbe3..75878dc3812 100644 --- a/.github/workflows/wac/pullRequests.wac.ts +++ b/.github/workflows/wac/pullRequests.wac.ts @@ -321,7 +321,7 @@ export const pullRequests = createWorkflow({ ...withCommonParams( [ { name: "Install dependencies", run: "yarn --immutable" }, - { name: "Check types for Cypress tests", run: "yarn cy:ts" } + { name: "Check types for E2E tests", run: "yarn e2e:ts" } ], { "working-directory": DIR_WEBINY_JS } ) diff --git a/.github/workflows/wac/pullRequestsCommandE2e.wac.ts b/.github/workflows/wac/pullRequestsCommandE2e.wac.ts index 88afdba0b9d..897506074f7 100644 --- a/.github/workflows/wac/pullRequestsCommandE2e.wac.ts +++ b/.github/workflows/wac/pullRequestsCommandE2e.wac.ts @@ -2,11 +2,11 @@ import { createWorkflow, NormalJob } from "github-actions-wac"; import { createDeployWebinySteps, createGlobalBuildCacheSteps, + createInstallationTestSteps, createInstallBuildSteps, createRunBuildCacheSteps, createSetupVerdaccioSteps, - createYarnCacheSteps, - withCommonParams + createYarnCacheSteps } from "./steps/index.js"; import { AWS_REGION, BUILD_PACKAGES_RUNNER, NODE_OPTIONS } from "./utils/index.js"; import { createJob } from "./jobs/index.js"; @@ -30,11 +30,12 @@ const createCheckoutPrSteps = () => } ] as NonNullable; -const createCypressJobs = (dbSetup: string) => { +// Scaffold a project, deploy it to AWS, then run the installation test against the deployed Admin +// app. One variant per storage setup ("ddb", "ddb-os"). +const createE2eJobs = (dbSetup: string) => { const jobNames = { constants: `e2e-wby-cms-${dbSetup}-constants`, - projectSetup: `e2e-wby-cms-${dbSetup}-project-setup`, - cypressTests: `e2e-wby-cms-${dbSetup}-cypress-tests` + projectSetup: `e2e-wby-cms-${dbSetup}-project-setup` }; const dbDisplayName = dbSetup === "ddb-os" ? "DDB+OS" : "DDB"; @@ -43,18 +44,11 @@ const createCypressJobs = (dbSetup: string) => { needs: ["baseBranch", "constants", "build"], name: `Constants - ${dbSetup.toUpperCase()}`, outputs: { - "cypress-folders": "${{ steps.list-cypress-folders.outputs.cypress-folders }}", "pulumi-backend-url": "${{ steps.pulumi-backend-url.outputs.pulumi-backend-url }}" }, checkout: { path: DIR_WEBINY_JS }, steps: [ ...createCheckoutPrSteps(), - { - name: "List Cypress tests folders", - id: "list-cypress-folders", - run: 'echo "cypress-folders=$(node scripts/listCypressTestsFolders.js)" >> $GITHUB_OUTPUT', - "working-directory": DIR_WEBINY_JS - }, { name: "Get Pulumi backend URL", id: "get-pulumi-backend-url", @@ -64,7 +58,6 @@ const createCypressJobs = (dbSetup: string) => { }); const env: Record = { - CYPRESS_MAILOSAUR_API_KEY: "${{ secrets.CYPRESS_MAILOSAUR_API_KEY }}", PULUMI_CONFIG_PASSPHRASE: "${{ secrets.PULUMI_CONFIG_PASSPHRASE }}", PULUMI_SECRETS_PROVIDER: "${{ secrets.PULUMI_SECRETS_PROVIDER }}", WEBINY_PULUMI_BACKEND: `\${{ needs.${jobNames.constants}.outputs.pulumi-backend-url }}`, @@ -82,9 +75,6 @@ const createCypressJobs = (dbSetup: string) => { const projectSetupJob: NormalJob = createJob({ needs: ["baseBranch", "constants", jobNames.constants, "checkComment"], name: `E2E (${dbSetup.toUpperCase()}) - Project setup`, - outputs: { - "cypress-config": "${{ steps.save-cypress-config.outputs.cypress-config }}" - }, environment: "next", env, awsAuth: true, @@ -193,39 +183,11 @@ const createCypressJobs = (dbSetup: string) => { `gh api repos/\${{ github.repository }}/issues/comments/$COMMENT_ID -X PATCH --field body=@/tmp/comment.txt` ].join("\n") }, - ...withCommonParams( - [ - // Commented this out b/c of an issue. Basically, the - // script fails b/c its output is not pure JSON string. - // { - // name: "Deployment Summary", - // run: `${runNodeScript( - // "printDeploymentSummary", - // `../${DIR_TEST_PROJECT}` - // )} >> $GITHUB_STEP_SUMMARY` - // }, - { - name: "Create Cypress config", - run: `yarn setup-cypress --projectFolder ../${DIR_TEST_PROJECT}` - }, - { - name: "Save Cypress config", - id: "save-cypress-config", - run: "echo \"cypress-config=$(cat cypress-tests/cypress.config.ts | tr -d '\\t\\n\\r')\" >> $GITHUB_OUTPUT" - }, - { - name: "Install Cypress binary", - run: "cd cypress-tests && yarn cypress install" - }, - { - name: "Cypress - run installation wizard test", - run: 'yarn cy:run --browser chrome --spec "cypress/e2e/adminInstallation/**/*.cy.js"' - } - ], - { - "working-directory": DIR_WEBINY_JS - } - ) + ...createInstallationTestSteps({ + workingDirectory: DIR_WEBINY_JS, + adminUrl: "${{ steps.admin-url.outputs.admin-url }}", + artifactName: `e2e-results-${dbSetup}` + }) ] }); @@ -270,7 +232,7 @@ export const pullRequestsCommandE2e = createWorkflow({ uses: "peter-evans/create-or-update-comment@v2", with: { "issue-number": "${{ github.event.issue.number }}", - body: "Cypress E2E tests have been initiated (for more information, click [here](https://github.com/webiny/webiny-js/actions/runs/${{ github.run_id }})). :sparkles:\n\n| Database | Status | Admin URL |\n| --- | --- | --- |\n| DDB | 🔄 Deploying... | - |\n| DDB+OS | 🔄 Deploying... | - |" + body: "E2E tests have been initiated (for more information, click [here](https://github.com/webiny/webiny-js/actions/runs/${{ github.run_id }})). :sparkles:\n\n| Database | Status | Admin URL |\n| --- | --- | --- |\n| DDB | 🔄 Deploying... | - |\n| DDB+OS | 🔄 Deploying... | - |" } } ] @@ -334,7 +296,7 @@ export const pullRequestsCommandE2e = createWorkflow({ } ] }), - ...createCypressJobs("ddb"), - ...createCypressJobs("ddb-os") + ...createE2eJobs("ddb"), + ...createE2eJobs("ddb-os") } }); diff --git a/.github/workflows/wac/push.wac.ts b/.github/workflows/wac/push.wac.ts index dee95822222..898e897a682 100644 --- a/.github/workflows/wac/push.wac.ts +++ b/.github/workflows/wac/push.wac.ts @@ -11,6 +11,7 @@ import { createJob } from "./jobs/index.js"; import { createDeployWebinySteps, createGlobalBuildCacheSteps, + createInstallationTestSteps, createInstallBuildSteps, createRunBuildCacheSteps, createSetupVerdaccioSteps, @@ -43,23 +44,16 @@ const runBuildCacheSteps = createRunBuildCacheSteps({ const createE2EJobs = (storageOps: AbstractStorageOps) => { const jobNames = { constants: `e2eTests-${storageOps.shortId}-constants`, - projectSetup: `e2eTests-${storageOps.shortId}-setup`, - cypressTests: `e2eTests-${storageOps.shortId}-cypress` + projectSetup: `e2eTests-${storageOps.shortId}-setup` }; const constantsJob: NormalJob = createJob({ name: `E2E (${storageOps.displayName}) - Constants`, needs: ["build"], outputs: { - "cypress-folders": "${{ steps.list-cypress-folders.outputs.cypress-folders }}", "pulumi-backend-url": "${{ steps.pulumi-backend-url.outputs.pulumi-backend-url }}" }, steps: [ - { - name: "List Cypress tests folders", - id: "list-cypress-folders", - run: 'echo "cypress-folders=$(node scripts/listCypressTestsFolders.js)" >> $GITHUB_OUTPUT' - }, { name: "Get Pulumi backend URL", id: "get-pulumi-backend-url", @@ -69,7 +63,6 @@ const createE2EJobs = (storageOps: AbstractStorageOps) => { }); const env: Record = { - CYPRESS_MAILOSAUR_API_KEY: "${{ secrets.CYPRESS_MAILOSAUR_API_KEY }}", PULUMI_CONFIG_PASSPHRASE: "${{ secrets.PULUMI_CONFIG_PASSPHRASE }}", PULUMI_SECRETS_PROVIDER: "${{ secrets.PULUMI_SECRETS_PROVIDER }}", WEBINY_PULUMI_BACKEND: `\${{ needs.${jobNames.constants}.outputs.pulumi-backend-url }}`, @@ -89,9 +82,6 @@ const createE2EJobs = (storageOps: AbstractStorageOps) => { needs: ["constants", "build", jobNames.constants], "runs-on": BUILD_PACKAGES_RUNNER, name: `E2E (${storageOps.displayName}) - Project setup`, - outputs: { - "cypress-config": "${{ steps.save-cypress-config.outputs.cypress-config }}" - }, environment: "next", env, checkout: { @@ -186,81 +176,23 @@ const createE2EJobs = (storageOps: AbstractStorageOps) => { } ] : []), - ...withCommonParams( - [ - // Commented this out b/c of an issue. Basically, the - // script fails b/c its output is not pure JSON string. - // { - // name: "Deployment Summary", - // run: `${runNodeScript( - // "printDeploymentSummary", - // `../${DIR_TEST_PROJECT}` - // )} >> $GITHUB_STEP_SUMMARY` - // }, - { - name: "Create Cypress config", - run: `yarn setup-cypress --projectFolder ../${DIR_TEST_PROJECT}` - }, - { - name: "Save Cypress config", - id: "save-cypress-config", - run: "echo \"cypress-config=$(cat cypress-tests/cypress.config.ts | tr -d '\\t\\n\\r')\" >> $GITHUB_OUTPUT" - }, - { - name: "Install Cypress binary", - run: "cd cypress-tests && yarn cypress install" - }, - { - name: "Cypress - run installation wizard test", - run: 'yarn cy:run --browser chrome --spec "cypress/e2e/adminInstallation/**/*.cy.js"' - } - ], - { "working-directory": DIR_WEBINY_JS } - ) + { + name: "Extract admin app URL", + id: "admin-url", + "working-directory": DIR_TEST_PROJECT, + run: `echo "admin-url=$(yarn webiny output admin --env dev --json 2>/dev/null | jq -r '.appUrl // empty')" >> $GITHUB_OUTPUT` + }, + ...createInstallationTestSteps({ + workingDirectory: DIR_WEBINY_JS, + adminUrl: "${{ steps.admin-url.outputs.admin-url }}", + artifactName: `e2e-results-${storageOps.shortId}` + }) ] }); - // We're disabling Cypress tests for now, as they need to be updated for v6. - // We'll probably enable them in a later phase. - // const cypressTestsJob = createJob({ - // name: `$\{{ matrix.cypress-folder }} (${storageOps.shortId}, $\{{ matrix.os }}, Node v$\{{ matrix.node }})`, - // needs: ["constants", jobNames.constants, jobNames.projectSetup], - // strategy: { - // "fail-fast": false, - // matrix: { - // os: ["ubuntu-latest"], - // node: [NODE_VERSION], - // "cypress-folder": `$\{{ fromJson(needs.${jobNames.constants}.outputs.cypress-folders) }}` - // } - // }, - // environment: "next", - // env, - // checkout: { path: DIR_WEBINY_JS }, - // steps: [ - // ...yarnCacheSteps, - // ...runBuildCacheSteps, - // ...installBuildSteps, - // ...withCommonParams( - // [ - // { - // name: "Set up Cypress config", - // run: `echo '$\{{ needs.${jobNames.projectSetup}.outputs.cypress-config }}' > cypress-tests/cypress.config.ts` - // }, - // { - // name: 'Cypress - run "${{ matrix.cypress-folder }}" tests', - // "timeout-minutes": 40, - // run: 'yarn cy:run --browser chrome --spec "${{ matrix.cypress-folder }}"' - // } - // ], - // { "working-directory": DIR_WEBINY_JS } - // ) - // ] - // }); - return { [jobNames.constants]: constantsJob, [jobNames.projectSetup]: projectSetupJob - // [jobNames.cypressTests]: cypressTestsJob }; }; @@ -424,7 +356,7 @@ export const push = createWorkflow({ ...withCommonParams( [ { name: "Install dependencies", run: "yarn --immutable" }, - { name: "Check types for Cypress tests", run: "yarn cy:ts" } + { name: "Check types for E2E tests", run: "yarn e2e:ts" } ], { "working-directory": DIR_WEBINY_JS } ) diff --git a/.github/workflows/wac/steps/createInstallationTestSteps.ts b/.github/workflows/wac/steps/createInstallationTestSteps.ts new file mode 100644 index 00000000000..6db550a488d --- /dev/null +++ b/.github/workflows/wac/steps/createInstallationTestSteps.ts @@ -0,0 +1,45 @@ +import type { NormalJob } from "github-actions-wac"; + +interface CreateInstallationTestStepsParams { + workingDirectory: string; + // Shell expression for the Admin app's URL. + adminUrl: string; + artifactName: string; +} + +/** + * The E2E smoke test: a freshly deployed project installs through the wizard and the admin lands + * in the dashboard. The test lives in `e2e/tests/installation.e2e.ts`. + */ +export const createInstallationTestSteps = ({ + workingDirectory, + adminUrl, + artifactName +}: CreateInstallationTestStepsParams): NonNullable => [ + { + name: "E2E - run installation wizard test", + "working-directory": workingDirectory, + env: { + E2E_ADMIN_URL: adminUrl, + E2E_INSTALLATION: "1", + E2E_TELEMETRY_DISABLED: "1" + }, + run: [ + "yarn workspace e2e-tests playwright install --with-deps chromium", + "yarn e2e --tag installation" + ].join("\n") + }, + { + // Report, screenshots and traces. + name: "E2E - upload installation test results", + if: "failure()", + uses: "actions/upload-artifact@v6", + with: { + name: artifactName, + "retention-days": 7, + "if-no-files-found": "ignore", + "include-hidden-files": true, + path: `${workingDirectory}/e2e/.e2e` + } + } +]; diff --git a/.github/workflows/wac/steps/index.ts b/.github/workflows/wac/steps/index.ts index fd623367d23..a3b9de96ee3 100644 --- a/.github/workflows/wac/steps/index.ts +++ b/.github/workflows/wac/steps/index.ts @@ -5,3 +5,4 @@ export * from "./createGlobalBuildCacheSteps.js"; export * from "./createRunBuildCacheSteps.js"; export * from "./createYarnCacheSteps.js"; export * from "./withCommonParams.js"; +export * from "./createInstallationTestSteps.js"; diff --git a/.github/workflows/wac/v5_pullRequestsCommandCypress.wac.ts b/.github/workflows/wac/v5_pullRequestsCommandCypress.wac.ts deleted file mode 100644 index 885fee45ec1..00000000000 --- a/.github/workflows/wac/v5_pullRequestsCommandCypress.wac.ts +++ /dev/null @@ -1,331 +0,0 @@ -import { createWorkflow, NormalJob } from "github-actions-wac"; -import { - createGlobalBuildCacheSteps, - createInstallBuildSteps, - createRunBuildCacheSteps, - createSetupVerdaccioSteps, - createYarnCacheSteps, - withCommonParams -} from "./steps"; -import { AWS_REGION, BUILD_PACKAGES_RUNNER, NODE_OPTIONS, NODE_VERSION } from "./utils"; -import { createJob } from "./jobs"; - -// Will print "next" or "dev". Important for caching (via actions/cache). -const DIR_WEBINY_JS = "${{ needs.baseBranch.outputs.base-branch }}"; -const DIR_TEST_PROJECT = "new-webiny-project"; - -const installBuildSteps = createInstallBuildSteps({ workingDirectory: DIR_WEBINY_JS }); -const yarnCacheSteps = createYarnCacheSteps({ workingDirectory: DIR_WEBINY_JS }); -const globalBuildCacheSteps = createGlobalBuildCacheSteps({ workingDirectory: DIR_WEBINY_JS }); -const runBuildCacheSteps = createRunBuildCacheSteps({ workingDirectory: DIR_WEBINY_JS }); - -const createDeployWebinySteps = ({ workingDirectory = "dev" } = {}) => { - return [ - { - name: "Deploy Core", - "working-directory": workingDirectory, - run: "yarn webiny deploy core --env dev" - }, - { - name: "Deploy API", - "working-directory": workingDirectory, - run: "yarn webiny deploy api --env dev" - }, - { - name: "Deploy Admin Area", - "working-directory": workingDirectory, - run: "yarn webiny deploy admin --env dev" - }, - { - name: "Deploy Website", - "working-directory": workingDirectory, - run: "yarn webiny deploy website --env dev" - } - ]; -}; - -const createCheckoutPrSteps = () => - [ - { - name: "Checkout Pull Request", - "working-directory": DIR_WEBINY_JS, - run: "gh pr checkout ${{ github.event.issue.number }}", - env: { GITHUB_TOKEN: "${{ secrets.GH_TOKEN }}" } - } - ] as NonNullable; - -const createCypressJobs = (dbSetup: string) => { - const jobNames = { - constants: `e2e-wby-cms-${dbSetup}-constants`, - projectSetup: `e2e-wby-cms-${dbSetup}-project-setup`, - cypressTests: `e2e-wby-cms-${dbSetup}-cypress-tests` - }; - - const constantsJob: NormalJob = createJob({ - needs: ["baseBranch", "constants", "build"], - name: `Constants - ${dbSetup.toUpperCase()}`, - outputs: { - "cypress-folders": "${{ steps.list-cypress-folders.outputs.cypress-folders }}", - "pulumi-backend-url": "${{ steps.pulumi-backend-url.outputs.pulumi-backend-url }}" - }, - checkout: { path: DIR_WEBINY_JS }, - steps: [ - ...createCheckoutPrSteps(), - { - name: "List Cypress tests folders", - id: "list-cypress-folders", - run: 'echo "cypress-folders=$(node scripts/listCypressTestsFolders.js)" >> $GITHUB_OUTPUT', - "working-directory": DIR_WEBINY_JS - }, - { - name: "Get Pulumi backend URL", - id: "get-pulumi-backend-url", - run: `echo "pulumi-backend-url=\${{ secrets.WEBINY_PULUMI_BACKEND }}\${{ github.run_id }}_${dbSetup}" >> $GITHUB_OUTPUT` - } - ] - }); - - const env: Record = { - CYPRESS_MAILOSAUR_API_KEY: "${{ secrets.CYPRESS_MAILOSAUR_API_KEY }}", - PULUMI_CONFIG_PASSPHRASE: "${{ secrets.PULUMI_CONFIG_PASSPHRASE }}", - PULUMI_SECRETS_PROVIDER: "${{ secrets.PULUMI_SECRETS_PROVIDER }}", - WEBINY_PULUMI_BACKEND: `\${{ needs.${jobNames.constants}.outputs.pulumi-backend-url }}` - }; - - if (dbSetup === "ddb-os") { - env["AWS_OPENSEARCH_DOMAIN_NAME"] = "${{ secrets.V5_OPENSEARCH_DOMAIN_NAME }}"; - env["OPENSEARCH_ENDPOINT"] = "${{ secrets.V5_OPENSEARCH_ENDPOINT }}"; - env["OPENSEARCH_USERNAME"] = "${{ secrets.V5_OPENSEARCH_USERNAME }}"; - env["OPENSEARCH_PASSWORD"] = "${{ secrets.V5_OPENSEARCH_PASSWORD }}"; - env["OPENSEARCH_INDEX_PREFIX"] = "${{ github.run_id }}_"; - } - - const projectSetupJob: NormalJob = createJob({ - needs: ["baseBranch", "constants", jobNames.constants], - name: `E2E (${dbSetup.toUpperCase()}) - Project setup`, - outputs: { - "cypress-config": "${{ steps.save-cypress-config.outputs.cypress-config }}" - }, - environment: "next", - env, - awsAuth: true, - checkout: { path: DIR_WEBINY_JS }, - steps: [ - ...createCheckoutPrSteps(), - ...yarnCacheSteps, - ...runBuildCacheSteps, - ...installBuildSteps, - ...createSetupVerdaccioSteps({ workingDirectory: DIR_WEBINY_JS }), - { - name: 'Create ".npmrc" file in the project root, with a dummy auth token', - "working-directory": DIR_WEBINY_JS, - run: "echo '//localhost:4873/:_authToken=\"dummy-auth-token\"' > .npmrc" - }, - { - name: "Version and publish to Verdaccio", - "working-directory": DIR_WEBINY_JS, - run: "yarn release --type=verdaccio" - }, - { - name: "Create verdaccio-files artifact", - uses: "actions/upload-artifact@v6", - with: { - name: `verdaccio-files-${dbSetup}`, - "retention-days": 1, - "include-hidden-files": true, - path: [DIR_WEBINY_JS + "/.verdaccio/", DIR_WEBINY_JS + "/.verdaccio.yaml"].join( - "\n" - ) - } - }, - { - name: "Disable Webiny telemetry", - run: 'mkdir ~/.webiny && echo \'{ "id": "ci", "telemetry": false }\' > ~/.webiny/config\n' - }, - { - name: "Create a new Webiny project", - run: `npx create-webiny-project@local-npm ${DIR_TEST_PROJECT} --tag local-npm --no-interactive --assign-to-yarnrc '{"npmRegistryServer":"http://localhost:4873","unsafeHttpWhitelist":["localhost"]}' --template-options '{"region":"\${{ env.AWS_REGION }}","storageOps":"${dbSetup}"}' -` - }, - { - name: "Print CLI version", - "working-directory": DIR_TEST_PROJECT, - run: "yarn webiny --version" - }, - { - name: "Create project-files artifact", - uses: "actions/upload-artifact@v6", - with: { - name: `project-files-${dbSetup}`, - "retention-days": 1, - "include-hidden-files": true, - path: [ - `${DIR_TEST_PROJECT}/`, - `!${DIR_TEST_PROJECT}/node_modules/**/*`, - `!${DIR_TEST_PROJECT}/**/node_modules/**/*`, - `!${DIR_TEST_PROJECT}/.yarn/cache/**/*` - ].join("\n") - } - }, - ...createDeployWebinySteps({ workingDirectory: DIR_TEST_PROJECT }), - ...withCommonParams( - [ - { - name: "Create Cypress config", - run: `yarn setup-cypress --projectFolder ../${DIR_TEST_PROJECT}` - }, - { - name: "Save Cypress config", - id: "save-cypress-config", - run: "echo \"cypress-config=$(cat cypress-tests/cypress.config.ts | tr -d '\\t\\n\\r')\" >> $GITHUB_OUTPUT" - }, - { - name: "Install Cypress binary", - run: "cd cypress-tests && yarn cypress install" - }, - { - name: "Cypress - run installation wizard test", - run: 'yarn cy:run --browser chrome --spec "cypress/e2e/adminInstallation/**/*.cy.js"' - } - ], - { - "working-directory": DIR_WEBINY_JS - } - ) - ] - }); - - const cypressTestsJob = createJob({ - name: `\${{ matrix.cypress-folder }} (${dbSetup}, \${{ matrix.os }}, Node v\${{ matrix.node }})`, - needs: ["baseBranch", "constants", jobNames.constants, jobNames.projectSetup], - strategy: { - "fail-fast": false, - matrix: { - os: ["ubuntu-latest"], - node: [NODE_VERSION], - "cypress-folder": `\${{ fromJson(needs.${jobNames.constants}.outputs.cypress-folders) }}` - } - }, - environment: "next", - env, - checkout: { path: "${{ needs.baseBranch.outputs.base-branch }}" }, - steps: [ - ...createCheckoutPrSteps(), - ...yarnCacheSteps, - ...runBuildCacheSteps, - ...installBuildSteps, - { - name: "Set up Cypress config", - "working-directory": DIR_WEBINY_JS, - run: `echo '\${{ needs.${jobNames.projectSetup}.outputs.cypress-config }}' > cypress-tests/cypress.config.ts` - }, - { - name: "Install Cypress binary", - "working-directory": DIR_WEBINY_JS, - run: "cd cypress-tests && yarn cypress install" - }, - { - name: 'Cypress - run "${{ matrix.cypress-folder }}" tests', - "timeout-minutes": 40, - "working-directory": DIR_WEBINY_JS, - run: 'yarn cy:run --browser chrome --spec "${{ matrix.cypress-folder }}"' - } - ] - }); - - return { - [jobNames.constants]: constantsJob, - [jobNames.projectSetup]: projectSetupJob, - [jobNames.cypressTests]: cypressTestsJob - }; -}; - -export const v5_PullRequestsCommandCypress = createWorkflow({ - name: "(v5) Pull Requests Command - Cypress", - on: "issue_comment", - env: { - NODE_OPTIONS, - AWS_REGION - }, - jobs: { - checkComment: createJob({ - name: `Check comment for /v5_cypress`, - if: "${{ github.event.issue.pull_request }}", - checkout: false, - steps: [ - { - name: "Check for Command", - id: "command", - uses: "xt0rted/slash-command-action@v2", - with: { - "repo-token": "${{ secrets.GITHUB_TOKEN }}", - command: "v5_cypress", - reaction: "true", - "reaction-type": "eyes", - "allow-edits": "false", - "permission-level": "write" - } - }, - { - name: "Create comment", - uses: "peter-evans/create-or-update-comment@v2", - with: { - "issue-number": "${{ github.event.issue.number }}", - body: "Cypress E2E tests have been initiated (for more information, click [here](https://github.com/webiny/webiny-js/actions/runs/${{ github.run_id }})). :sparkles:" - } - } - ] - }), - baseBranch: createJob({ - needs: "checkComment", - name: "Get base branch", - outputs: { - "base-branch": "${{ steps.base-branch.outputs.base-branch }}" - }, - steps: [ - { - name: "Get base branch", - id: "base-branch", - env: { GITHUB_TOKEN: "${{ secrets.GH_TOKEN }}" }, - run: 'echo "base-branch=$(gh pr view ${{ github.event.issue.number }} --json baseRefName -q .baseRefName)" >> $GITHUB_OUTPUT' - } - ] - }), - constants: createJob({ - needs: "baseBranch", - name: "Create constants", - outputs: { - "global-cache-key": "${{ steps.global-cache-key.outputs.global-cache-key }}", - "run-cache-key": "${{ steps.run-cache-key.outputs.run-cache-key }}" - }, - checkout: false, - steps: [ - { - name: "Create global cache key", - id: "global-cache-key", - run: `echo "global-cache-key=\${{ needs.baseBranch.outputs.base-branch }}-\${{ runner.os }}-$(/bin/date -u "+%m%d")-\${{ vars.RANDOM_CACHE_KEY_SUFFIX }}" >> $GITHUB_OUTPUT` - }, - { - name: "Create workflow run cache key", - id: "run-cache-key", - run: 'echo "run-cache-key=${{ github.run_id }}-${{ github.run_attempt }}-${{ vars.RANDOM_CACHE_KEY_SUFFIX }}" >> $GITHUB_OUTPUT' - } - ] - }), - build: createJob({ - name: "Build", - needs: ["baseBranch", "constants"], - checkout: { path: DIR_WEBINY_JS }, - "runs-on": BUILD_PACKAGES_RUNNER, - steps: [ - ...createCheckoutPrSteps(), - ...yarnCacheSteps, - ...globalBuildCacheSteps, - ...installBuildSteps, - ...runBuildCacheSteps - ] - }), - ...createCypressJobs("ddb"), - ...createCypressJobs("ddb-os") - } -}); diff --git a/.gitignore b/.gitignore index d198acc67ed..721b40439bb 100644 --- a/.gitignore +++ b/.gitignore @@ -25,10 +25,6 @@ apps/**/build/ .verdaccio .history *.tsbuildinfo -cypress.json -cypress.config.ts -cypress/screenshots/* -cypress-tests/cypress/screenshots/* .pulumi logs.txt Pulumi.* diff --git a/cypress-tests/cypress/e2e/admin/account/account.cy.js b/cypress-tests/cypress/e2e/admin/account/account.cy.js deleted file mode 100644 index 99072479297..00000000000 --- a/cypress-tests/cypress/e2e/admin/account/account.cy.js +++ /dev/null @@ -1,54 +0,0 @@ -import uniqid from "uniqid"; - -context("Account Module", () => { - beforeEach(() => cy.login()); - - it("should be able to update account details and immediately see changes in the top-right user menu", () => { - const [firstName, lastName] = [uniqid(), uniqid()]; - - cy.visit("/account"); - cy.findByTestId("account.email"); - cy.should("value", Cypress.expose("DEFAULT_ADMIN_USER_USERNAME")); - cy.findByTestId("account.password"); - cy.should("value", ""); - cy.findByLabelText("First Name").clear().type(firstName); - cy.findByLabelText("Last Name").clear().type(lastName); - cy.findByTestId("account.updatebutton").click(); - cy.findByText("Account saved successfully!"); - cy.should("exist"); - - // Make sure the changes were propagated in the top-right user menu, - cy.findByTestId("logged-in-user-menu-avatar").click(); - cy.findByTestId("logged-in-user-menu-list").within(() => { - cy.findByText(Cypress.expose("DEFAULT_ADMIN_USER_USERNAME")); - cy.should("exist"); - cy.findByText(`${firstName} ${lastName}`); - cy.should("exist"); - }); - }); - // TODO - fix this test (FM issue?) - it.skip("should be able to change avatar", () => { - cy.visit("/account"); - cy.get('div[data-role="select-image"]').click(); - - cy.findByTestId("fm-list-wrapper").dropFile("sample.jpeg", "image/jpeg"); - cy.findByText("File upload complete.").should("exist"); - cy.get('div[data-testid="fm-list-wrapper-file"]:first-child').click(); - - cy.get("div.mdc-layout-grid div > img").should("exist"); - cy.get('[data-testid="image-preview"] > img').should("exist"); - - cy.findByTestId("account.updatebutton").click(); - cy.contains("Account saved successfully").should("be.visible"); - - // Refresh page to assert the avatar persists. - cy.reload(); - cy.get('[data-testid="image-preview"] > img').should("exist"); - - // Delete the newly avatar image. - cy.findByTestId("remove-image").click({ force: true }); - cy.get('[data-testid="image-preview"] > img').should("not.exist"); - cy.findByTestId("account.updatebutton").click(); - cy.findByText("Account saved successfully!"); - }); -}); diff --git a/cypress-tests/cypress/e2e/admin/fileManager/searchAndFilterFiles.disabled.js b/cypress-tests/cypress/e2e/admin/fileManager/searchAndFilterFiles.disabled.js deleted file mode 100644 index d3fe717cb87..00000000000 --- a/cypress-tests/cypress/e2e/admin/fileManager/searchAndFilterFiles.disabled.js +++ /dev/null @@ -1,294 +0,0 @@ -import uniqid from "uniqid"; - -/** - * Sometimes file details drawer gets hidden due the race condition in "showFileDetails" and "hideFileDetails" dispatch-actions. - * That's why we make sure the drawer in visible. - */ -const openFileDetails = index => { - cy.waitUntil( - () => - cy - .findByTestId("fm-list-wrapper") - .within(() => { - cy.findAllByTestId("fm-list-wrapper-file") - .eq(index) - .within(() => { - cy.findByTestId("fm-file-wrapper-file-info-icon").click({ - force: true - }); - }); - }) - .then(() => - cy.findByTestId("fm.file-details.drawer").then($el => { - const [aside] = $el; - return aside.classList.contains("mdc-drawer--open"); - }) - ), - { - description: `Wait until "File Details" model is visible` - } - ); -}; - -const deleteFile = () => { - openFileDetails(0); - // Delete file - cy.findByTestId("fm-delete-file-button").click(); - cy.findByTestId("fm-delete-file-confirmation-dialog").within(() => { - cy.findByText("Confirm").click(); - }); - cy.findByText("File deleted successfully."); - - cy.waitUntil( - () => - cy.findByTestId("fm.file-details.drawer").then($el => { - const [aside] = $el; - return !aside.classList.contains("mdc-drawer--open"); - }), - { - description: "wait until file details is hidden" - } - ); -}; - -const updateFileName = newName => { - // Edit the name and save it - cy.findByTestId("fm.file-details.drawer").within(() => { - cy.findByPlaceholderText("Enter name").clear().type(newName).blur(); - }); - cy.findByText("Name successfully updated.").should("exist"); - // Exit file details view - cy.get("body").click(); - - cy.waitUntil( - () => - cy.findByTestId("fm.file-details.drawer").then($el => { - const [aside] = $el; - return !aside.classList.contains("mdc-drawer--open"); - }), - { - description: "wait until file details is hidden" - } - ); -}; - -const addTagsToFile = (tags, map) => { - // Edit tag and save it - cy.findByTestId("fm.file-details.drawer").within(() => { - // Save name value for later - cy.findByPlaceholderText(/Enter name/i).then($input => { - tags.forEach(tag => { - map[tag] = $input.attr("value"); - }); - }); - - cy.findByText(/Add tags.../i).click(); - // Add tags - tags.forEach(tag => { - cy.findByPlaceholderText(/homepage asset/i) - .clear() - .type(tag); - cy.wait(1000); - cy.findByText(tag).click(); - }); - // Save changes - cy.findByTestId("fm.tags.submit").click(); - }); - // Verify success message - cy.findByText("Tags successfully updated.").should("exist"); - // Exit file details view - cy.get("body").click(); - // Check tags in list - cy.findByTestId("fm.left-drawer.tag-list").within(() => { - tags.forEach(tag => { - cy.findByText(tag).should("exist"); - }); - }); - cy.waitUntil( - () => - cy.findByTestId("fm.file-details.drawer").then($el => { - const [aside] = $el; - return !aside.classList.contains("mdc-drawer--open"); - }), - { - description: "wait until file details is hidden" - } - ); -}; - -context("File Manager - Update file details", () => { - const files = [ - { fileName: "sample.jpeg", type: "image/jpeg" }, - { fileName: "sample_2.jpeg", type: "image/jpeg" } - ]; - - beforeEach(() => { - cy.login(); - cy.visit("/"); - // Open drawer - cy.findByTestId("apps-menu").click(); - // Open "File Manage" view - cy.findByTestId("admin-drawer-footer-menu-file-manager").click(); - - // Check if there are existing file and delete them - cy.fmListFiles({}).then(files => { - for (let i = 0; i < files.length; i++) { - deleteFile(); - } - }); - // Add files - files.forEach(({ fileName, type }) => { - cy.findByTestId("fm-list-wrapper").dropFile(fileName, type); - }); - cy.findByText("File upload complete.").should("exist"); - // All files should be there - cy.findByTestId("fm-list-wrapper").within(() => { - cy.findAllByTestId("fm-list-wrapper-file").should("have.length", files.length); - }); - }); - - // TODO - fix this test - it.skip("should update file's name and search by name", () => { - // Edit files name one by one - const newFileName1 = uniqid("File "); - const newFileName2 = uniqid("File "); - - // Select a file and open its details - openFileDetails(0); - - updateFileName(newFileName1); - - // Check file name is there in the list - cy.findByTestId("fm-list-wrapper").within(() => { - cy.findAllByTestId("fm-list-wrapper-file") - .first() - .within(() => { - cy.findByText(newFileName1).should("exist"); - }); - }); - - // Select a file and open its details - openFileDetails(1); - updateFileName(newFileName2); - // Check file name is there in the list - cy.findByTestId("fm-list-wrapper").within(() => { - cy.findAllByTestId("fm-list-wrapper-file") - .first() - .next() - .within(() => { - cy.findByText(newFileName2).should("exist"); - }); - }); - /** - * The search input is not responding to the first couple of clicks(interactions) while running the Cypress test. - * So, at the moment we forcefully "awake" the sleeping input element before continuing with the search. - */ - - cy.get(`[data-testid="file-manager.search-input"]`).as("search-input"); - cy.get("@search-input").dblclick(); - cy.get("@search-input").dblclick(); - cy.get("@search-input").should("be.focused"); - - // Search files by name - cy.get("@search-input").type(newFileName1); - cy.get(".react-spinner-material").should("not.exist"); - // File should be in list - cy.findByTestId("fm-list-wrapper").within(() => { - cy.findByText(newFileName1).should("exist"); - }); - cy.get("@search-input").clear().type(newFileName2); - cy.get(".react-spinner-material").should("not.exist"); - // File should be in list - cy.findByTestId("fm-list-wrapper").within(() => { - cy.findByText(newFileName2).should("exist"); - }); - - // Clear search - cy.get("@search-input").clear(); - }); - - // TODO - fix this test - it.skip("should add tags, search and by tags", () => { - // Add tags one by one - const tagNew = "new"; - const tagOld = "old"; - const tagCommon = "common"; - - const map = {}; - - openFileDetails(0); - // Add tags to first file - addTagsToFile([tagNew, tagCommon], map); - /** - * Make sure tags are indexed in elastic search before continue. - */ - cy.waitUntil(() => cy.fmListTags().then(tags => tags.length === 2), { - description: `Wait until tags are indexed`, - timeout: 2000, - interval: 2000 - }); - - openFileDetails(1); - // Add tags to second file - addTagsToFile([tagOld, tagCommon], map); - /** - * Make sure tags are indexed in elastic search before continue. - */ - cy.waitUntil(() => cy.fmListTags().then(tags => tags.length === 3), { - description: `Wait until tags are indexed`, - timeout: 2000, - interval: 2000 - }); - - /** - * The search input is not responding to the first couple of clicks(interactions) while running the Cypress test. - * So, at the moment we forcefully "awake" the sleeping input element before continuing with the search. - */ - cy.findByPlaceholderText("Search by filename or tags").as("search-input"); - cy.get("@search-input").dblclick(); - cy.get("@search-input").dblclick(); - cy.get("@search-input").should("be.focused"); - - // Search files by tags - cy.get("@search-input").type(tagNew); - cy.get(".react-spinner-material").should("not.exist"); - // File should be in list - cy.findByTestId("fm-list-wrapper").within(() => { - cy.findByText(map[tagNew]).should("exist"); - }); - - cy.get("@search-input").clear().type(tagOld); - cy.get(".react-spinner-material").should("not.exist"); - // File should be in list - cy.findByTestId("fm-list-wrapper").within(() => { - cy.findByText(map[tagOld]).should("exist"); - }); - - // Search file for common tag - cy.get("@search-input").clear().type(tagCommon); - cy.get(".react-spinner-material").should("not.exist"); - // Both files should be in list - cy.findByTestId("fm-list-wrapper").within(() => { - cy.findByText(map[tagOld]).should("exist"); - cy.findByText(map[tagNew]).should("exist"); - }); - - // Clear search - cy.get("@search-input").clear(); - cy.get(".react-spinner-material").should("not.exist"); - - // Filter files by selecting a tag - cy.findByTestId("fm.left-drawer.tag-list").within(() => { - cy.findByText(tagNew).click(); - }); - cy.get(".react-spinner-material").should("not.exist"); - // File should be in list - cy.findByTestId("fm-list-wrapper").within(() => { - cy.findByText(map[tagNew]).should("exist"); - }); - // Clear filter - cy.findByTestId("fm.left-drawer.tag-list").within(() => { - cy.findByText(tagNew).click(); - }); - }); -}); diff --git a/cypress-tests/cypress/e2e/admin/fileManager/uploadImage.cy.js b/cypress-tests/cypress/e2e/admin/fileManager/uploadImage.cy.js deleted file mode 100644 index c12035f3c21..00000000000 --- a/cypress-tests/cypress/e2e/admin/fileManager/uploadImage.cy.js +++ /dev/null @@ -1,294 +0,0 @@ -context("File Manager View - CRUD", () => { - beforeEach(() => { - cy.login(); - - cy.fmDeleteAllFiles(); - - cy.visit("/"); - - // Open main menu. - cy.findByTestId("apps-menu").click(); - - // Open "File Manage" view. - cy.findByTestId("admin-drawer-footer-menu-file-manager").click(); - }); - - // TODO - fix this test - it.skip("should upload, edit and delete image", () => { - // Drop file - cy.findByTestId("fm-list-wrapper").dropFile("sample.jpeg", "image/jpeg"); - cy.findByText("File upload complete.").should("exist"); - - // Open file details - cy.findByTestId("fm-list-wrapper").within(() => { - cy.findAllByTestId("fm-list-wrapper-file") - .first() - .within(() => { - cy.findByTestId("fm-file-wrapper-file-info-icon").click({ force: true }); - }); - }); - - // Assert the aside file details is displayed. - cy.findByTestId("fm.file-details.drawer").should("be.visible"); - cy.findByTestId("fm.file-details.drawer").find("img").should("be.visible"); - cy.get("span").contains("File details").should("be.visible"); - - // Edit file. - cy.findByTestId("fm-edit-image-button").click(); - cy.findByTestId("fm-image-editor-dialog") - .should("be.visible") - .within(() => { - cy.findByTestId("dialog-cancel").click(); - }); - // Delete file. - cy.findByTestId("fm-delete-file-button").click(); - cy.findByTestId("fm-delete-file-confirmation-dialog").within(() => { - cy.findByTestId("confirmationdialog-confirm-action").click(); - }); - cy.findByText("File deleted successfully."); - }); - - // TODO - fix this test - it.skip("only images should contain thumbnail and only images should be displayed as avatar options", () => { - // Add 5 files (text/pdf/png/gif/jpeg). - const files = [ - { fileName: "textfile.txt", type: "text/plain" }, - { fileName: "pdfDoc.pdf", type: "text/plain" }, - { fileName: "pngPicture.PNG", type: "image/png" }, - { fileName: "gifPicture.GIF", type: "image/gif" }, - { fileName: "sample.jpeg", type: "image/jpeg" } - ]; - files.forEach(({ fileName, type }) => { - cy.findByTestId("fm-list-wrapper").dropFile(fileName, type); - }); - cy.findByText("File upload complete.").should("exist"); - - // All files should be there. - cy.findByTestId("fm-list-wrapper").within(() => { - cy.findAllByTestId("fm-list-wrapper-file").should("have.length", files.length); - }); - - // Assert that only 3 files out of 5 have thumbnail image. - cy.get('div[data-testid="fm-file-wrapper-file-preview"] img').should("have.length", 3); - - cy.visit("/account"); - cy.get('div[data-role="select-image"]').click(); - - // Assert that for avatar we can choose only from 3 files (png/gif/jpeg). - cy.findAllByTestId("fm-list-wrapper-file").should("have.length", 3); - }); - - // TODO - fix this test - it.skip("should edit and save file using the flip feature", () => { - const fileName = "sample_2.jpeg"; - - // Drop file - cy.findByTestId("fm-list-wrapper").dropFile(fileName, "image/jpeg"); - cy.findByText("File upload complete.").should("exist"); - - // Open file details - cy.findByTestId("fm-list-wrapper").within(() => { - cy.findAllByTestId("fm-list-wrapper-file") - .first() - .within(() => { - cy.findByTestId("fm-file-wrapper-file-info-icon").click({ force: true }); - }); - }); - - // Assert the aside file details is displayed. - cy.findByTestId("fm.file-details.drawer").should("be.visible"); - cy.findByTestId("fm.file-details.drawer").find("img").should("be.visible"); - cy.get("span").contains("File details").should("be.visible"); - - // Edit and save file by using Flip option. - cy.findByTestId("fm-edit-image-button").click(); - cy.findByTestId("fm-image-editor-dialog") - .should("be.visible") - .within(() => { - cy.findByTestId("flip-item").click(); - cy.findByTestId("button-apply").click(); - cy.findByTestId("dialog-accept").click(); - }); - - cy.wait(2000); - - // TODO: Restore the snackbar on file upload - // cy.contains("File upload complete.").should("be.visible"); - // cy.contains("File upload complete.").should("not.exist"); - - cy.visit("/"); - cy.findByTestId("apps-menu").click(); - cy.findByTestId("admin-drawer-footer-menu-file-manager").click(); - - // Assert that there are displayed both initial item and edited one. - cy.get('div[data-testid="fm-list-wrapper-file"]:nth-child(1)') - .get('div[data-testid="fm-file-wrapper-file-label"]') - .contains(fileName); - cy.get('div[data-testid="fm-list-wrapper-file"]:nth-child(2)') - .get('div[data-testid="fm-file-wrapper-file-label"]') - .contains(fileName); - }); - - it.skip("should test minimum and maximum allowed file upload size", () => { - cy.visit("/settings/file-manager/general"); - - const fileDetails = [ - { - maximumFileUploadBytesLimit: 500, - expectedUploadMessage: "Max size exceeded." - }, - { - maximumFileUploadBytesLimit: 26214401, - expectedUploadMessage: "File upload complete." - } - ]; - - fileDetails.forEach(fileDetail => { - cy.visit("/settings/file-manager/general"); - cy.findByLabelText("Maximum file upload size") - .clear() - .type(fileDetail.maximumFileUploadBytesLimit); - cy.contains("Save Settings").click(); - cy.contains("Settings updated successfully.").should("be.visible"); - - cy.findByTestId("apps-menu").click(); - cy.contains("Settings updated successfully.").should("not.exist"); - cy.findByTestId("admin-drawer-footer-menu-file-manager").click(); - cy.findByTestId("fm-list-wrapper").dropFile("sample.jpeg", "image/jpeg"); - - cy.contains(fileDetail.expectedUploadMessage).should("exist"); - }); - }); - // TODO - fix this test - it.skip("should test adding duplicate tag", () => { - const fileName = "sample_2.jpeg"; - - // Drop file - cy.findByTestId("fm-list-wrapper").dropFile(fileName, "image/jpeg"); - cy.findByText("File upload complete.").should("exist"); - - // Open file details - cy.findByTestId("fm-list-wrapper").within(() => { - cy.findAllByTestId("fm-list-wrapper-file") - .first() - .within(() => { - cy.findByTestId("fm-file-wrapper-file-info-icon").click({ force: true }); - }); - }); - - cy.findByText("File details").should("be.visible"); - - const tagName = `tag-${Cypress.expose("TEST_RUN_ID")}`; - - // Edit file - cy.findByTestId("fm.tags.add").click(); - cy.get('input[placeholder="homepage asset"]').type(tagName); - cy.get("ul > li > span").contains(tagName).click(); - cy.get('input[placeholder="homepage asset"]').type(tagName); - cy.get("ul > li > span").contains("No results.").should("be.visible"); - }); - - // TODO - fix this test - it.skip("should test adding 5 tags per file", () => { - const fileDetails = [ - { - fileName: "pngPicture.PNG", - fileType: "image/png", - tagValues: [ - "webiny1_img1", - "webiny2_img1", - "webiny3_img1", - "webiny4_img1", - "webiny5_img1" - ] - }, - { - fileName: "sample_2.jpeg", - fileType: "image/jpeg", - tagValues: [ - "webiny1_img2", - "webiny2_img2", - "webiny3_img2", - "webiny4_img2", - "webiny5_img2" - ] - }, - { - fileName: "sample.jpeg", - fileType: "image/jpeg", - tagValues: [ - "webiny1_img3", - "webiny2_img3", - "webiny3_img3", - "webiny4_img3", - "webiny5_img3" - ] - } - ]; - - // Upload 3 files and add 5 tags per file. - fileDetails.forEach(fileDetail => { - cy.findByTestId("fm-list-wrapper").dropFile(fileDetail.fileName, fileDetail.fileType); - cy.findByText("File upload complete.").should("exist"); - - cy.findByTestId("fm-list-wrapper").within(() => { - cy.findAllByTestId("fm-list-wrapper-file") - .first() - .within(() => { - cy.findByTestId("fm-file-wrapper-file-info-icon").click({ force: true }); - }); - }); - - cy.get("span").contains("File details").should("be.visible"); - - cy.findByTestId("fm.tags.add").click(); - - cy.get('input[placeholder="homepage asset"]').type(fileDetail.tagValues[0]); - cy.get("ul > li > span").contains(fileDetail.tagValues[0]).click(); - - cy.get('input[placeholder="homepage asset"]').type(fileDetail.tagValues[1]); - cy.get("ul > li > span").contains(fileDetail.tagValues[1]).click(); - - cy.get('input[placeholder="homepage asset"]').type(fileDetail.tagValues[2]); - cy.get("ul > li > span").contains(fileDetail.tagValues[2]).click(); - - cy.get('input[placeholder="homepage asset"]').type(fileDetail.tagValues[3]); - cy.get("ul > li > span").contains(fileDetail.tagValues[3]).click(); - - cy.get('input[placeholder="homepage asset"]').type(fileDetail.tagValues[4]); - cy.get("ul > li > span").contains(fileDetail.tagValues[4]).click(); - - cy.findByTestId("fm.tags.submit").click(); - cy.contains("Tags successfully updated.").should("be.visible"); - - cy.visit("/settings/file-manager/general"); - cy.findByTestId("apps-menu").click(); - cy.findByTestId("admin-drawer-footer-menu-file-manager").click(); - }); - - // Assert all the 15 tags are visible. - fileDetails.forEach(fileTags => { - cy.contains(fileTags.tagValues[0]).should("be.visible"); - cy.contains(fileTags.tagValues[1]).should("be.visible"); - cy.contains(fileTags.tagValues[2]).should("be.visible"); - }); - }); - - // TODO - fix this test - it.skip("should test drag and drop bulk files", () => { - const fileNames = ["sample.jpeg", "sample_2.jpeg", "pngPicture.PNG"]; - - // Drag and drop bulk 3 files. - cy.uploadBulkFiles('[data-testid="fm-list-wrapper"]', fileNames); - - cy.findByText("File upload complete.").should("be.visible"); - - // Wait until "File upload complete." element disappears. - cy.contains("File upload complete.").should("not.exist"); - - // Assert the files are visible. - for (let i = 0; i < fileNames.length; i++) { - cy.contains(fileNames[i]).should("exist"); - } - }); -}); diff --git a/cypress-tests/cypress/e2e/admin/headlessCms/contentEntry/contentEntries.disabled.js b/cypress-tests/cypress/e2e/admin/headlessCms/contentEntry/contentEntries.disabled.js deleted file mode 100644 index 13ea988ad00..00000000000 --- a/cypress-tests/cypress/e2e/admin/headlessCms/contentEntry/contentEntries.disabled.js +++ /dev/null @@ -1,284 +0,0 @@ -import uniqid from "uniqid"; -import kebabCase from "lodash/kebabCase"; -import upperFirst from "lodash/upperFirst"; -import camelCase from "lodash/camelCase"; -import { CONTENT_MODEL_DATA } from "../mocks"; - -describe("Headless CMS - Content Entries", () => { - context("CRUD", () => { - const newModel = uniqid("Book-"); - const singularApiName = upperFirst(camelCase(uniqid("Book"))); - const pluralApiName = upperFirst(camelCase(uniqid("Books"))); - - let model; - let group; - // Runs once before all tests in the block - before(() => { - return cy - .cmsCreateContentModelGroup({ - data: { name: uniqid("Group-"), icon: "fas/star" } - }) - .then(data => { - group = data; - return cy - .cmsCreateContentModel({ - data: { - name: newModel, - modelId: kebabCase(newModel.toLowerCase()), - singularApiName, - pluralApiName, - group: group.id, - description: "Testing 123" - } - }) - .then(data => { - model = data; - return cy.cmsUpdateContentModel({ - modelId: data.modelId, - data: CONTENT_MODEL_DATA - }); - }); - }); - }); - - beforeEach(() => cy.login()); - - after(() => { - cy.waitUntil( - () => { - return cy - .cmsDeleteContentModel({ modelId: model.modelId }) - .then(data => data === true); - }, - { - description: `Wait until "ContentModel" is deleted` - } - ); - - cy.waitUntil( - () => cy.cmsDeleteContentModelGroup({ id: group.id }).then(data => data === true), - { - description: `Wait until "ContentModelGroup" is deleted` - } - ); - }); - - it("should create, edit, publish, unpublish, and delete content entry", () => { - cy.visit("/cms/content-models"); - - cy.findByTestId("default-data-list").within(() => { - cy.get("li") - .first() - .within(() => { - cy.findByText(newModel).should("exist"); - cy.findByTestId("cms-view-content-model-button").click({ force: true }); - }); - }); - - // Create an entry - const newEntryTitle = `Atomic Habits`; - const newEntryEdition = "4"; - const newEntryTitle2 = newEntryTitle + " - 2nd"; - - // a) Click on "New Entry" button - cy.findByTestId("new-entry-button").should("exist"); - cy.findByTestId("new-entry-button").click(); - //cy.findAllByTestId("new-entry-button").first().click({ force: true }); - - // Loading should not be visible - cy.get(".react-spinner-material").should("not.exist"); - - // b) Fill entry details - cy.findByTestId("cms-content-form").within(() => { - cy.findByTestId("fr.input.text.Title").clear(); - cy.findByTestId("fr.input.text.Title").type(newEntryTitle); - cy.findByTestId("fr.input.number.Edition").clear(); - cy.findByTestId("fr.input.number.Edition").type(newEntryEdition); - }); - // c) Save entry - cy.findByTestId("cms-content-save-content-button").click(); - // Loading should not be visible - cy.get(".react-spinner-material").should("not.exist"); - // d) Verify success message - cy.findByText(`${newModel} entry created successfully!`).should("exist"); - /** - * As ACO was introduced, there is a new step - navigate to root folder - */ - cy.acoNavigateToRootFolder(); - cy.wait(500); - - // Check the new entry in list - cy.findByTestId("default-data-list").within(() => { - cy.get("tbody") - .first() - .within(() => { - cy.get("tr").within(() => { - cy.findByText(newEntryTitle).should("exist"); - cy.findByText(/Draft \(v1\)/i).should("exist"); - }); - }); - }); - - // Loading should not be visible - cy.get(".react-spinner-material").should("not.exist"); - // We should navigate to the new entry - cy.get("div.cms-data-list-record-title") - .first() - .within(() => { - cy.findByText(newEntryTitle).should("exist"); - }) - .click({ force: true }); - cy.get(".mdc-text-field__input").should("exist"); - - // Publish entry - cy.findByTestId("cms-content-save-publish-content-button").click(); - cy.findByTestId("cms-confirm-save-and-publish").within(() => { - cy.findByRole("button", { name: "Confirm" }).click(); - }); - cy.get(".react-spinner-material").should("not.exist"); - cy.findByText(/Successfully published revision/i).should("exist"); - - /** - * As ACO was introduced, there is a new step - navigate to root folder - */ - cy.acoNavigateToRootFolder(); - // Loading should not be visible - cy.get(".react-spinner-material").should("not.exist"); - cy.wait(500); - - // Check publish status - cy.findByTestId("default-data-list").within(() => { - cy.get("tbody") - .first() - .within(() => { - cy.get("tr").within(() => { - cy.findByText(newEntryTitle).should("exist"); - cy.findByText(/Published \(v1\)/i).should("exist"); - }); - }); - }); - // Navigate to published entry - cy.get("div.cms-data-list-record-title") - .first() - .within(() => { - cy.findByText(newEntryTitle).should("exist"); - }) - .click({ force: true }); - cy.get(".mdc-text-field__input").should("exist").wait(100); - - // Edit an entry - cy.findByTestId("fr.input.text.Title").clear(); - cy.wait(500); - cy.findByTestId("fr.input.text.Title").wait(200).type(newEntryTitle2); - cy.findByTestId("fr.input.text.Title").should("have.value", newEntryTitle2); - cy.findByTestId("cms-content-save-content-button").click({ force: true }); - - // Loading should not be visible - cy.get(".react-spinner-material").should("not.exist"); - /** - * As ACO was introduced, there is a new step - navigate to root folder - */ - cy.acoNavigateToRootFolder(); - // Loading should not be visible - cy.get(".react-spinner-material").should("not.exist"); - - cy.findByTestId("default-data-list").should("exist"); - - // Check the update entry in list - cy.findByTestId("default-data-list").within(() => { - cy.get("tbody") - .first() - .within(() => { - cy.get("tr").within(() => { - cy.findByText(newEntryTitle2).should("exist"); - cy.findByText(/Draft \(v2\)/i).should("exist"); - }); - }); - }); - - // Navigate to updated entry - cy.get("div.cms-data-list-record-title") - .first() - .within(() => { - cy.findByText(newEntryTitle2).should("exist"); - }) - .click({ force: true }); - cy.get(".mdc-text-field__input").should("exist"); - - // Publish entry - cy.findByTestId("cms-content-save-publish-content-button").click(); - - cy.findByTestId("cms-confirm-save-and-publish").within(() => { - cy.findByRole("button", { name: "Confirm" }).click(); - }); - cy.findByText(/Successfully published revision/i).should("exist"); - - // Loading should not be visible - cy.get(".react-spinner-material").should("not.exist"); - - cy.acoNavigateToRootFolder(); - // Loading should not be visible - cy.get(".react-spinner-material").should("not.exist"); - - // Check publish status - cy.findByTestId("default-data-list").within(() => { - cy.get("tbody") - .first() - .within(() => { - cy.get("tr").within(() => { - cy.findByText(newEntryTitle2).should("exist"); - cy.findByText(/Published \(v2\)/i).should("exist"); - }); - }); - }); - - // Navigate to published updated entry - cy.get("div.cms-data-list-record-title") - .first() - .within(() => { - cy.findByText(newEntryTitle2).should("exist"); - }) - .click({ force: true }); - cy.get(".mdc-text-field__input").should("exist"); - - // Check revisions tab - cy.findByTestId("cms.content-form.tabs.revisions").click(); - // check revisions - cy.findByTestId("cms.content-form.revisions").within(() => { - cy.get("li") - .first() - .within(() => { - cy.findByTestId("cms.revision.status.published").should("exist"); - }); - cy.get("li") - .next() - .within(() => { - cy.findByTestId("cms.revision.status.locked").should("exist"); - }); - }); - - // unpublish latest revision - cy.findByTestId("cms.content-form.revisions").within(() => { - cy.get("li") - .first() - .within(() => { - cy.findByTestId("cms.revision.status.published").should("exist"); - cy.findByTestId("cms.content-form.revisions.more-options").click(); - }); - }); - cy.findByTestId("cms.revision.unpublish").click(); - cy.findByText(/Successfully unpublished revision/i).should("exist"); - - cy.findByTestId("cms.content-form.tabs.content").click(); - - // Delete the entry - cy.findByTestId("cms.content-form.header.more-options").click(); - cy.findByTestId("cms.content-form.header.delete").click(); - cy.findByTestId("cms.content-form.header.delete-dialog").within(() => { - cy.findByText(/Delete content entry/i); - cy.findByRole("button", { name: "Confirm" }).click(); - }); - cy.findByText(/deleted successfully!/i).should("exist"); - }); - }); -}); diff --git a/cypress-tests/cypress/e2e/admin/headlessCms/contentEntry/searchSortAndFilterEntries.disabled.js b/cypress-tests/cypress/e2e/admin/headlessCms/contentEntry/searchSortAndFilterEntries.disabled.js deleted file mode 100644 index eb142a5abbd..00000000000 --- a/cypress-tests/cypress/e2e/admin/headlessCms/contentEntry/searchSortAndFilterEntries.disabled.js +++ /dev/null @@ -1,224 +0,0 @@ -import uniqid from "uniqid"; -import kebabCase from "lodash/kebabCase"; -import upperFirst from "lodash/upperFirst"; -import camelCase from "lodash/camelCase"; -import { CONTENT_MODEL_DATA } from "../mocks"; - -const STATUS = { - draft: "draft", - published: "published", - all: "all" -}; - -const createContentEntry = ({ model, entries }) => { - // Create an entry - const newEntryTitle = uniqid(`Atomic Habits `); - const newEntryEdition = Math.round(Math.random() * 10); - // Save for later - entries.push({ title: newEntryTitle }); - cy.wait(500); - cy.get(".react-spinner-material").should("not.exist"); - - // a) Click on "New Entry" button - cy.findAllByTestId("new-entry-button").first().click({ force: true }); - // b) Fill entry details - cy.wait(500); - cy.findByTestId("fr.input.text.Title").type(newEntryTitle); - cy.findByTestId("fr.input.number.Edition").type(newEntryEdition.toString()); - // c) Save entry - cy.findByTestId("cms-content-save-content-button").click({ force: true }); - // d) Verify success message - cy.findByText(`${model.name} entry created successfully!`).should("exist"); - cy.get(".react-spinner-material").should("not.exist"); - /** - * As ACO was introduced, there is a new step - navigate to root folder - */ - cy.acoNavigateToRootFolder(); -}; - -const deleteContentEntry = () => { - // Select entry - cy.get("div.cms-data-list-record-title").first().click({ force: true }); - // Delete the entry - cy.findByTestId("cms.content-form.header.more-options").click(); - cy.findByTestId("cms.content-form.header.delete").click(); - cy.findByTestId("cms.content-form.header.delete-dialog").within(() => { - cy.findByText(/Delete content entry/i); - cy.findByText(/Confirm/i).click({ force: true }); - }); - // Verify - cy.findByText(/deleted successfully!/i).should("exist"); - cy.get(".react-spinner-material").should("not.exist"); - /** - * As ACO was introduced, there is a new step - navigate to root folder - */ - cy.acoNavigateToRootFolder(); -}; - -context("Search, Sort and Filter Content Entries", () => { - const newModel = uniqid("Book-"); - const singularApiName = upperFirst(camelCase(uniqid("Book"))); - const pluralApiName = upperFirst(camelCase(uniqid("Books"))); - const totalEntries = 3; - const entries = []; - let createdModel; - let createdGroup; - // Runs once before all tests in the block - before(() => { - cy.cmsCreateContentModelGroup({ - data: { name: uniqid("Group-"), icon: "fas/star" } - }).then(group => { - createdGroup = group; - cy.cmsCreateContentModel({ - data: { - ...CONTENT_MODEL_DATA, - name: newModel, - modelId: kebabCase(newModel.toLowerCase()), - singularApiName, - pluralApiName, - group: group.id, - description: "Testing 123" - } - }).then(model => { - createdModel = model; - cy.visit(`/cms/content-entries/${model.modelId}?folderId=root`); - cy.wait(2000); - // Create few entries - for (let i = 0; i < totalEntries; i++) { - createContentEntry({ model, entries }); - } - }); - }); - }); - - beforeEach(() => cy.login()); - - after(() => { - cy.login(); - cy.visit(`/cms/content-entries/${createdModel.modelId}?folderId=root`); - - cy.wait(2000); - // Delete all entries - for (let i = 0; i < totalEntries; i++) { - deleteContentEntry(); - } - - cy.waitUntil( - () => - cy - .cmsDeleteContentModel({ modelId: createdModel.modelId }) - .then(data => data === true), - { - description: `Wait until "ContentModel" is deleted` - } - ); - - cy.waitUntil( - () => - cy.cmsDeleteContentModelGroup({ id: createdGroup.id }).then(data => data === true), - { - description: `Wait until "ContentModelGroup" is deleted` - } - ); - }); - - it("should search entries", () => { - // Should show "no records found" when searching for non existing entry - cy.findByTestId("default-data-list.search").within(() => { - cy.get(".search__input").wait(200).clear(); - cy.get(".search__input").wait(200).type("NON_EXISTING_ENTRY"); - cy.wait(500); - }); - cy.get(".title__container").within(() => { - cy.findByText("No results found.").should("exist"); - }); - - // Should able to search for a specific entry - cy.findByTestId("default-data-list.search").within(() => { - cy.get(".search__input").wait(100).clear(); - cy.get(".search__input").wait(100).type(entries[0].title); - cy.wait(500); - }); - - cy.get(".cms-data-list-record-title").should("have.length", 1); - cy.get(".cms-data-list-record-title") - .first() - .within(() => { - cy.findByText(entries[0].title).should("exist"); - }); - - // Clear search - cy.findByTestId("default-data-list.search").within(() => { - cy.get(".search__input").wait(100).clear(); - }); - }); - - it("should sort entries", () => { - cy.visit(`/cms/content-entries/${createdModel.modelId}?folderId=root`); - // Loading should not be visible - cy.get(".react-spinner-material").should("not.exist"); - cy.wait(500); - // Loading should not be visible - cy.get(".react-spinner-material").should("not.exist"); - - // Last entry should be on the top - cy.findByTestId("default-data-list").within(() => { - cy.get(".cms-data-list-record-title") - .first() - .within(() => { - cy.findByText(entries[totalEntries - 1].title).should("exist"); - }); - }); - - // Sort by ASC - cy.get(".cms-aco-list-savedOn").within(() => { - cy.get("div").first().click(); - }); - cy.wait(500); - // Loading should not be visible - cy.get(".react-spinner-material").should("not.exist"); - - // First entry should be on the top - cy.findByTestId("default-data-list").within(() => { - cy.get(".cms-data-list-record-title") - .first() - .within(() => { - cy.findByText(entries[0].title).should("exist"); - }); - }); - }); - - it("should filter entries by status", () => { - cy.visit(`/cms/content-entries/${createdModel.modelId}?folderId=root`); - - // open the filters bar - cy.findByTestId("cms.list-entries.toggle-filters").click(); - - cy.findByTestId("filters-container").within(() => { - cy.get("select").first().select(STATUS.draft); - cy.wait(500); - }); - - // Loading should not be visible - cy.get(".react-spinner-material").should("not.exist"); - - // Should contain all entries - cy.get(".cms-data-list-record-title").should("have.length", entries.length); - - // Get all items with "published" status - - cy.findByTestId("filters-container").within(() => { - cy.get("select").first().select(STATUS.published); - cy.wait(500); - }); - - // Loading should not be visible - cy.get(".react-spinner-material").should("not.exist"); - - // Should contain no entries - cy.get(".cms-data-list-record-title").should("have.length", 0); - cy.get(".title__container").within(() => { - cy.findByText("No results found.").should("exist"); - }); - }); -}); diff --git a/cypress-tests/cypress/e2e/admin/headlessCms/contentModel/contentModels.cy.js b/cypress-tests/cypress/e2e/admin/headlessCms/contentModel/contentModels.cy.js deleted file mode 100644 index 1b23f79d3da..00000000000 --- a/cypress-tests/cypress/e2e/admin/headlessCms/contentModel/contentModels.cy.js +++ /dev/null @@ -1,348 +0,0 @@ -import uniqid from "uniqid"; -import lodashUpperFirst from "lodash/upperFirst"; -import lodashCamelCase from "lodash/camelCase"; - -context("Headless CMS - Content Models CRUD", () => { - beforeEach(() => cy.login()); - - it("should create, edit, and delete content model - no default fields", () => { - // 1. Visit /cms/content-models - cy.visit("/cms/content-models"); - // 2. Create a new content model - const uniqueId = uniqid(); - const newModelDescription = `Creating a new model for testing.`; - - // 2.1 Add name - // 2.2 Description - // 2.3 Click save button - cy.findByTestId("new-record-button").click(); - cy.findByTestId("cms-new-content-model-modal").within(() => { - // Ensures we start typing once the content model group select is loaded. - // This is important because otherwise, typing into the first field would be partially lost. - cy.contains("Ungrouped").should("exist"); - - cy.findByTestId("cms.newcontentmodeldialog.name") - .focus() - // waiting seems to improve flakyness of this test - .wait(500) - .type(`Book - ${uniqueId}`) - .wait(500); - // add api singular and plural names - cy.findByTestId("cms.newcontentmodeldialog.singularApiName") - .focus() - .wait(500) - .type(lodashUpperFirst(lodashCamelCase(`Book${uniqueId}`))) - .wait(500); - cy.findByTestId("cms.newcontentmodeldialog.pluralApiName") - .focus() - .wait(500) - .type(lodashUpperFirst(lodashCamelCase(`Books${uniqueId}`))) - .wait(500); - - cy.findByTestId("cms.newcontentmodeldialog.description").type(newModelDescription); - cy.findByTestId("cms.newcontentmodeldialog.defaultfields").uncheck(); - cy.findByRole("button", { name: "+ Create Model" }).click(); - }); - // 3. Editor - cy.wait(1000); - // 3.1 Editor -> Preview tab -> check message - cy.findByTestId("cms.editor.tab.preview").click(); - cy.findByText( - `Before previewing the form, please add at least one field to the content model.` - ).should("exist"); - // 3.2 Edit tab -> add text field and number field -> Save button - cy.findByTestId("cms.editor.tab.edit").click(); - cy.get(`[data-testid="cms-editor-fields-field-text"]`).drag( - `[data-testid="cms-editor-first-field-area"]`, - { - force: true - } - ); - cy.findByTestId("cms-editor-edit-fields-dialog").within(() => { - cy.findByTestId("cms.editor.field.settings.general.label") - .focus() - .wait(500) - .type("Title") - .wait(500); - cy.findByTestId("cms.editor.field.settings.save").click(); - }); - cy.wait(1000); - - cy.get(`[data-testid="cms-editor-fields-field-number"]`).drag( - `[data-testid="cms-editor-row-droppable-bottom-0"]`, - { force: true } - ); - cy.findByTestId("cms-editor-edit-fields-dialog").within(() => { - cy.findByTestId("cms.editor.field.settings.general.label") - .focus() - .wait(500) - .type("Edition") - .wait(500); - cy.findByTestId("cms.editor.field.settings.save").click(); - }); - cy.wait(1000); - // Saving the "Book" model should complete successfully. - cy.findByTestId("cms-editor-top-bar").within(() => { - cy.findByTestId("cms.editor.defaultbar.save").click(); - }); - cy.findByText(`Your content model was saved successfully!`).should("exist"); - // Get back to the list view - // Workaround for "@rmwc/icon-button" v14 issue: props duplication onto , causing multiple elements with same `data-testid`. - // Now targeting