diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index 59a1965d9676..514747f4f491 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -440,6 +440,8 @@ jobs: run: SUB_BUILD=PLATFORM ./gradlew --no-daemon assemble --scan - name: Run End-to-End Frontend Tests + env: + CYPRESS_WEBAPP_KEY: ${{ secrets.CYPRESS_WEBAPP_KEY }} run: ./tools/bin/e2e_test.sh # In case of self-hosted EC2 errors, remove this block. stop-frontend-test-runner: diff --git a/airbyte-webapp-e2e-tests/build.gradle b/airbyte-webapp-e2e-tests/build.gradle index df78f6404cd2..fc10a04ef1ad 100644 --- a/airbyte-webapp-e2e-tests/build.gradle +++ b/airbyte-webapp-e2e-tests/build.gradle @@ -13,8 +13,15 @@ node { task e2etest(type: NpmTask) { dependsOn npmInstall - - args = ['run', 'cypress:ci'] + // If the cypressWebappKey property has been set from the outside (see tools/bin/e2e_test.sh) + // we'll record the cypress session, otherwise we're not recording + def recordCypress = project.hasProperty('cypressWebappKey') && project.getProperty('cypressWebappKey') + if (recordCypress) { + environment = [CYPRESS_KEY: project.getProperty('cypressWebappKey')] + args = ['run', 'cypress:ci:record'] + } else { + args = ['run', 'cypress:ci'] + } inputs.files fileTree('cypress') inputs.file 'package.json' inputs.file 'package-lock.json' diff --git a/airbyte-webapp-e2e-tests/cypress.json b/airbyte-webapp-e2e-tests/cypress.json index 67b3f620bfcc..cd22f12502da 100644 --- a/airbyte-webapp-e2e-tests/cypress.json +++ b/airbyte-webapp-e2e-tests/cypress.json @@ -1,4 +1,5 @@ { + "projectId": "916nvw", "baseUrl": "http://localhost:3000", "testFiles": [ "base.spec.js", diff --git a/airbyte-webapp-e2e-tests/cypress/integration/connection.spec.js b/airbyte-webapp-e2e-tests/cypress/integration/connection.spec.js index 7c103f46a3bb..29cabfe39485 100644 --- a/airbyte-webapp-e2e-tests/cypress/integration/connection.spec.js +++ b/airbyte-webapp-e2e-tests/cypress/integration/connection.spec.js @@ -1,4 +1,8 @@ describe("Connection main actions", () => { + beforeEach(() => { + cy.initialSetupCompleted(); + }); + it("Create new connection", () => { cy.createTestConnection("Test connection source cypress", "Test destination cypress"); @@ -6,7 +10,7 @@ describe("Connection main actions", () => { cy.get("div").contains("Test destination cypress").should("exist"); }); - it.only("Update connection", () => { + it("Update connection", () => { cy.intercept("/api/v1/web_backend/connections/update").as("updateConnection"); cy.createTestConnection("Test update connection source cypress", "Test update connection destination cypress"); diff --git a/airbyte-webapp-e2e-tests/cypress/integration/destination.spec.js b/airbyte-webapp-e2e-tests/cypress/integration/destination.spec.js index 8d64a08263d8..94524c9135ac 100644 --- a/airbyte-webapp-e2e-tests/cypress/integration/destination.spec.js +++ b/airbyte-webapp-e2e-tests/cypress/integration/destination.spec.js @@ -1,4 +1,8 @@ describe("Destination main actions", () => { + beforeEach(() => { + cy.initialSetupCompleted(); + }); + it("Create new destination", () => { cy.createTestDestination("Test destination cypress"); diff --git a/airbyte-webapp-e2e-tests/cypress/integration/onboarding.spec.js b/airbyte-webapp-e2e-tests/cypress/integration/onboarding.spec.js index 3a8301160465..b6ad80ceb2b2 100644 --- a/airbyte-webapp-e2e-tests/cypress/integration/onboarding.spec.js +++ b/airbyte-webapp-e2e-tests/cypress/integration/onboarding.spec.js @@ -1,4 +1,8 @@ describe("Preferences actions", () => { + beforeEach(() => { + cy.initialSetupCompleted(false); + }); + it("Should redirect to onboarding after email is entered", () => { cy.visit("/preferences"); cy.url().should("include", `/preferences`); diff --git a/airbyte-webapp-e2e-tests/cypress/integration/source.spec.js b/airbyte-webapp-e2e-tests/cypress/integration/source.spec.js index 581251d4445c..8b486d47dcf0 100644 --- a/airbyte-webapp-e2e-tests/cypress/integration/source.spec.js +++ b/airbyte-webapp-e2e-tests/cypress/integration/source.spec.js @@ -1,4 +1,8 @@ describe("Source main actions", () => { + beforeEach(() => { + cy.initialSetupCompleted(); + }); + it("Create new source", () => { cy.createTestSource("Test source cypress"); diff --git a/airbyte-webapp-e2e-tests/cypress/support/commands/index.ts b/airbyte-webapp-e2e-tests/cypress/support/commands/index.ts index 3ffc02becb89..281bf7833b84 100644 --- a/airbyte-webapp-e2e-tests/cypress/support/commands/index.ts +++ b/airbyte-webapp-e2e-tests/cypress/support/commands/index.ts @@ -3,3 +3,4 @@ import "./sidebar"; import "./source"; import "./destination"; import "./connection"; +import "./workspaces"; diff --git a/airbyte-webapp-e2e-tests/cypress/support/commands/workspaces.js b/airbyte-webapp-e2e-tests/cypress/support/commands/workspaces.js new file mode 100644 index 000000000000..3111fc247cf2 --- /dev/null +++ b/airbyte-webapp-e2e-tests/cypress/support/commands/workspaces.js @@ -0,0 +1,10 @@ +Cypress.Commands.add("initialSetupCompleted", (completed = true) => { + // Modify the workspaces/list response to mark every workspace as "initialSetupComplete" to ensure we're not showing + // the setup/preference page for any workspace if this method got called. + cy.intercept("POST", "/api/v1/workspaces/list", (req) => { + req.continue(res => { + res.body.workspaces = res.body.workspaces.map(ws => ({ ...ws, initialSetupComplete: completed })); + res.send(res.body); + }); + }); +}); diff --git a/airbyte-webapp-e2e-tests/package.json b/airbyte-webapp-e2e-tests/package.json index 25eff6858bff..09a50a2b076b 100644 --- a/airbyte-webapp-e2e-tests/package.json +++ b/airbyte-webapp-e2e-tests/package.json @@ -4,7 +4,8 @@ "description": "Airbyte e2e testing", "scripts": { "cypress:open": "cypress open", - "cypress:ci": "CYPRESS_BASE_URL=http://localhost:8000 cypress run" + "cypress:ci": "CYPRESS_BASE_URL=http://localhost:8000 cypress run", + "cypress:ci:record": "CYPRESS_BASE_URL=http://localhost:8000 cypress run --record --key $CYPRESS_KEY" }, "eslintConfig": { "env": { diff --git a/tools/bin/e2e_test.sh b/tools/bin/e2e_test.sh index 7deb9bdf2437..e0e194e6eff3 100755 --- a/tools/bin/e2e_test.sh +++ b/tools/bin/e2e_test.sh @@ -16,11 +16,15 @@ mkdir -p /tmp/airbyte_local # Detach so we can run subsequent commands VERSION=dev TRACKING_STRATEGY=logging docker-compose up -d -trap 'echo "docker-compose logs:" && docker-compose logs -t --tail 1000 && docker-compose down && docker rm -f $(docker ps -q --filter name=airbyte_ci_pg)' EXIT +trap 'echo "docker-compose logs:" && docker-compose logs -t --tail 1000 && docker-compose down && docker stop airbyte_ci_pg' EXIT -docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=secret_password -e POSTGRES_DB=airbyte_ci --name airbyte_ci_pg postgres -echo "Waiting for services to begin" -sleep 30 # TODO need a better way to wait +docker run --rm -d -p 5433:5432 -e POSTGRES_PASSWORD=secret_password -e POSTGRES_DB=airbyte_ci --name airbyte_ci_pg postgres +echo "Waiting for health API to be available..." +# Retry loading the health API of the server to check that the server is fully available +until $(curl --output /dev/null --fail --silent --max-time 5 --head localhost:8001/api/v1/health); do + echo "Health API not available yet. Retrying in 10 seconds..." + sleep 10 +done echo "Running e2e tests via gradle" -SUB_BUILD=PLATFORM ./gradlew --no-daemon :airbyte-webapp-e2e-tests:e2etest +SUB_BUILD=PLATFORM ./gradlew --no-daemon :airbyte-webapp-e2e-tests:e2etest -PcypressWebappKey=$CYPRESS_WEBAPP_KEY