From 508692042bf3d18cf98eff7778722896730a101c Mon Sep 17 00:00:00 2001 From: Sofiia Zaitseva <108751383+SofiiaZaitseva@users.noreply.github.com> Date: Tue, 16 Aug 2022 20:51:48 +0200 Subject: [PATCH 01/11] add tests for PokeAPI --- .../cypress/commands/connection.ts | 8 +++- .../cypress/commands/source.ts | 28 ++++++++++++ .../cypress/integration/connection.spec.ts | 45 ++++++++++++++++++- 3 files changed, 78 insertions(+), 3 deletions(-) diff --git a/airbyte-webapp-e2e-tests/cypress/commands/connection.ts b/airbyte-webapp-e2e-tests/cypress/commands/connection.ts index e9a7ba8e31f79..413ac581484c0 100644 --- a/airbyte-webapp-e2e-tests/cypress/commands/connection.ts +++ b/airbyte-webapp-e2e-tests/cypress/commands/connection.ts @@ -1,12 +1,16 @@ import { submitButtonClick } from "./common"; import { createTestDestination } from "./destination"; -import { createTestSource } from "./source"; +import { createPokeTestSource, createTestSource } from "./source"; export const createTestConnection = (sourceName: string, destinationName: string) => { cy.intercept("/api/v1/sources/discover_schema").as("discoverSchema"); cy.intercept("/api/v1/web_backend/connections/create").as("createConnection"); - createTestSource(sourceName); + if (sourceName.includes("PokeAPI")){ + createPokeTestSource(sourceName) + } else { + createTestSource(sourceName); + } createTestDestination(destinationName); cy.wait(5000); diff --git a/airbyte-webapp-e2e-tests/cypress/commands/source.ts b/airbyte-webapp-e2e-tests/cypress/commands/source.ts index d5f59e92de8de..f5e14f2163163 100644 --- a/airbyte-webapp-e2e-tests/cypress/commands/source.ts +++ b/airbyte-webapp-e2e-tests/cypress/commands/source.ts @@ -20,6 +20,20 @@ export const fillPgSourceForm = (name: string) => { ); }; +export const fillPokeAPISourceForm = (name: string) => { + cy.intercept("/api/v1/source_definition_specifications/get").as( + "getSourceSpecifications" + ); + + cy.get("div[data-testid='serviceType']").click(); + cy.get("div").contains("PokeAPI").click(); + + cy.wait("@getSourceSpecifications"); + + cy.get("input[name=name]").clear().type(name); + cy.get("input[name='connectionConfiguration.pokemon_name']").type("luxray"); +}; + export const createTestSource = (name: string) => { cy.intercept("/api/v1/scheduler/sources/check_connection").as( "checkSourceUpdateConnection" @@ -34,6 +48,20 @@ export const createTestSource = (name: string) => { cy.wait("@createSource"); }; +export const createPokeTestSource = (name: string) => { + cy.intercept("/api/v1/scheduler/sources/check_connection").as( + "checkSourceUpdateConnection" + ); + cy.intercept("/api/v1/sources/create").as("createSource"); + + openNewSourceForm(); + fillPokeAPISourceForm(name); + submitButtonClick(); + + cy.wait("@checkSourceUpdateConnection"); + cy.wait("@createSource"); +}; + export const updateSource = (name: string, field: string, value: string) => { cy.intercept("/api/v1/sources/check_connection_for_update").as( "checkSourceConnection" diff --git a/airbyte-webapp-e2e-tests/cypress/integration/connection.spec.ts b/airbyte-webapp-e2e-tests/cypress/integration/connection.spec.ts index e8a05dfdd3481..eb09a55773447 100644 --- a/airbyte-webapp-e2e-tests/cypress/integration/connection.spec.ts +++ b/airbyte-webapp-e2e-tests/cypress/integration/connection.spec.ts @@ -29,9 +29,52 @@ describe("Connection main actions", () => { cy.get("div[data-testid='scheduleData.basicSchedule']").click(); cy.get("div[data-testid='Every hour']").click(); + cy.get("input[data-testid='prefixInput']").clear(); + cy.get("input[data-testid='prefixInput']").type('auto_test'); cy.get("button[type=submit]").first().click(); - cy.wait("@updateConnection"); + cy.wait("@updateConnection").then((interception) => { + assert.isNotNull(interception.response?.statusCode, '200'); cy.get("span[data-id='success-result']").should("exist"); + + + }) +}); + +it("Update connection (pokeAPI)", () => { + cy.intercept({ + method: "POST", + url: "/api/v1/web_backend/connections/updateNew"}).as("updateConnection"); + + //createTestConnection("Test update connection PokeAPI source cypress", "Test update connection destination cypress"); + + cy.visit("/source"); + cy.get("div").contains("Test update connection PokeAPI source cypress").click(); + cy.get("div").contains("Test update connection destination cypress").click(); + + cy.get("div[data-id='replication-step']").click(); + + cy.get("div[data-testid='schedule']").click(); + cy.get("div[data-testid='Every 5 minutes']").click(); + cy.get("input[data-testid='prefixInput']").clear().type('auto_test'); + cy.get("div.sc-jgbSNz.sc-gSAPjG.dmcQNW.kFkHkC.SyncCatalogField_catalogHeader__vtJPc input.sc-jSMfEi.dZkanq").check({force: true}); + //cy.get("div.sc-iBkjds.eXsTY").first().select('Full refresh | Append'); + cy.get("button[type=submit]").first().click(); + + cy.wait("@updateConnection").then((interception) => { + assert.isNotNull(interception.response?.statusCode, '200'); + expect(interception.request.method).to.eq('POST'); + cy.log(interception.request.body); + expect(interception.request).property('body').to.contain({ + name: 'Test update connection PokeAPI source cypress <> Test update connection destination cypress', + prefix: 'auto_test', + shedule: { + units: 5, + timeUnit: 'minutes' + } + }) + + }) + cy.get("span[data-id='success-result']").should("exist"); }); it("Delete connection", () => { From 78a9ffedb3f70888e2acea58103cece158769ad1 Mon Sep 17 00:00:00 2001 From: Sofiia Zaitseva <108751383+SofiiaZaitseva@users.noreply.github.com> Date: Wed, 17 Aug 2022 15:27:56 +0200 Subject: [PATCH 02/11] Update connection.spec.ts add body verification --- .../cypress/integration/connection.spec.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/airbyte-webapp-e2e-tests/cypress/integration/connection.spec.ts b/airbyte-webapp-e2e-tests/cypress/integration/connection.spec.ts index eb09a55773447..c5fff6d988ece 100644 --- a/airbyte-webapp-e2e-tests/cypress/integration/connection.spec.ts +++ b/airbyte-webapp-e2e-tests/cypress/integration/connection.spec.ts @@ -67,10 +67,13 @@ it("Update connection (pokeAPI)", () => { expect(interception.request).property('body').to.contain({ name: 'Test update connection PokeAPI source cypress <> Test update connection destination cypress', prefix: 'auto_test', - shedule: { + namespaceDefinition: 'source', + namespaceFormat: '${SOURCE_NAMESPACE}', + /*schedule: { units: 5, timeUnit: 'minutes' - } + },*/ + status: 'active', }) }) From 4e0ce12acde7173622eaaf304aed1f94847c1130 Mon Sep 17 00:00:00 2001 From: Sofiia Zaitseva <108751383+SofiiaZaitseva@users.noreply.github.com> Date: Mon, 22 Aug 2022 17:32:41 +0300 Subject: [PATCH 03/11] add page object model for update connection (poke api) test --- .../cypress/commands/connection.ts | 14 ++- .../cypress/integration/connection.spec.ts | 90 +++++++++++-------- .../cypress/pages/replicationPage.ts | 48 ++++++++++ .../cypress/pages/sourcePage.ts | 7 ++ 4 files changed, 117 insertions(+), 42 deletions(-) create mode 100644 airbyte-webapp-e2e-tests/cypress/pages/replicationPage.ts create mode 100644 airbyte-webapp-e2e-tests/cypress/pages/sourcePage.ts diff --git a/airbyte-webapp-e2e-tests/cypress/commands/connection.ts b/airbyte-webapp-e2e-tests/cypress/commands/connection.ts index 413ac581484c0..9219ba815acb2 100644 --- a/airbyte-webapp-e2e-tests/cypress/commands/connection.ts +++ b/airbyte-webapp-e2e-tests/cypress/commands/connection.ts @@ -6,11 +6,17 @@ export const createTestConnection = (sourceName: string, destinationName: string cy.intercept("/api/v1/sources/discover_schema").as("discoverSchema"); cy.intercept("/api/v1/web_backend/connections/create").as("createConnection"); - if (sourceName.includes("PokeAPI")){ - createPokeTestSource(sourceName) - } else { - createTestSource(sourceName); + switch (true) { + case sourceName.includes('PokeAPI'): + createPokeTestSource(sourceName) + break; + case sourceName.includes('Postgres'): + createTestSource(sourceName); + break; + default: + createTestSource(sourceName); } + createTestDestination(destinationName); cy.wait(5000); diff --git a/airbyte-webapp-e2e-tests/cypress/integration/connection.spec.ts b/airbyte-webapp-e2e-tests/cypress/integration/connection.spec.ts index c5fff6d988ece..b4ce35889c3c4 100644 --- a/airbyte-webapp-e2e-tests/cypress/integration/connection.spec.ts +++ b/airbyte-webapp-e2e-tests/cypress/integration/connection.spec.ts @@ -3,6 +3,8 @@ import { createTestConnection } from "commands/connection"; import { deleteDestination } from "commands/destination"; import { deleteSource } from "commands/source"; import { initialSetupCompleted } from "commands/workspaces"; +import { confirmStreamConfigurationChangedPopup, clickSaveChanges, selectSchedule, fillOutDestinationPrefix, goToReplicationTab, setupDestinationNamespaceCustomFormat, selectFullAppendSyncMode, checkSuccessResult} from "pages/replicationPage"; +import { openSourceDestinationFromGrid, goToSourcePage} from "pages/sourcePage"; describe("Connection main actions", () => { beforeEach(() => { @@ -38,47 +40,59 @@ describe("Connection main actions", () => { }) -}); - -it("Update connection (pokeAPI)", () => { - cy.intercept({ - method: "POST", - url: "/api/v1/web_backend/connections/updateNew"}).as("updateConnection"); - - //createTestConnection("Test update connection PokeAPI source cypress", "Test update connection destination cypress"); - - cy.visit("/source"); - cy.get("div").contains("Test update connection PokeAPI source cypress").click(); - cy.get("div").contains("Test update connection destination cypress").click(); - - cy.get("div[data-id='replication-step']").click(); - - cy.get("div[data-testid='schedule']").click(); - cy.get("div[data-testid='Every 5 minutes']").click(); - cy.get("input[data-testid='prefixInput']").clear().type('auto_test'); - cy.get("div.sc-jgbSNz.sc-gSAPjG.dmcQNW.kFkHkC.SyncCatalogField_catalogHeader__vtJPc input.sc-jSMfEi.dZkanq").check({force: true}); - //cy.get("div.sc-iBkjds.eXsTY").first().select('Full refresh | Append'); - cy.get("button[type=submit]").first().click(); - - cy.wait("@updateConnection").then((interception) => { - assert.isNotNull(interception.response?.statusCode, '200'); - expect(interception.request.method).to.eq('POST'); - cy.log(interception.request.body); - expect(interception.request).property('body').to.contain({ - name: 'Test update connection PokeAPI source cypress <> Test update connection destination cypress', - prefix: 'auto_test', - namespaceDefinition: 'source', - namespaceFormat: '${SOURCE_NAMESPACE}', - /*schedule: { + }); + + it("Update connection (pokeAPI)", () => { + cy.intercept({ + method: "POST", + url: "/api/v1/web_backend/connections/updateNew"}).as("updateConnection"); + + createTestConnection("Test update connection PokeAPI source cypress", "Test update connection Local JSON destination cypress"); + + goToSourcePage(); + openSourceDestinationFromGrid("Test update connection PokeAPI source cypress"); + openSourceDestinationFromGrid("Test update connection Local JSON destination cypress"); + + goToReplicationTab(); + + selectSchedule('Every 5 minutes'); + fillOutDestinationPrefix('auto_test'); + setupDestinationNamespaceCustomFormat('_test'); + selectFullAppendSyncMode(); + + clickSaveChanges(); + confirmStreamConfigurationChangedPopup(); + + cy.wait("@updateConnection").then((interception) => { + assert.isNotNull(interception.response?.statusCode, '200'); + expect(interception.request.method).to.eq('POST'); + expect(interception.request).property('body').to.contain({ + name: 'Test update connection PokeAPI source cypress <> Test update connection Local JSON destination cypressConnection name', + prefix: 'auto_test', + namespaceDefinition: 'customformat', + namespaceFormat: '${SOURCE_NAMESPACE}_test', + status: 'active', + }); + expect(interception.request.body.schedule).to.contain({ units: 5, timeUnit: 'minutes' - },*/ - status: 'active', + }); + + expect(interception.request.body.syncCatalog.streams[0].config).to.contain({ + aliasName: 'pokemon', + destinationSyncMode: 'append', + selected: true, + }); + + expect(interception.request.body.syncCatalog.streams[0].stream).to.contain({ + name: "pokemon", + }); + expect(interception.request.body.syncCatalog.streams[0].stream.supportedSyncModes).to.contain( + 'full_refresh' + ); }) - - }) - cy.get("span[data-id='success-result']").should("exist"); -}); + checkSuccessResult(); + }); it("Delete connection", () => { createTestConnection("Test delete connection source cypress", "Test delete connection destination cypress"); diff --git a/airbyte-webapp-e2e-tests/cypress/pages/replicationPage.ts b/airbyte-webapp-e2e-tests/cypress/pages/replicationPage.ts new file mode 100644 index 0000000000000..9b340e006c54f --- /dev/null +++ b/airbyte-webapp-e2e-tests/cypress/pages/replicationPage.ts @@ -0,0 +1,48 @@ +const scheduleDropdown = "div[data-testid='schedule']"; +const scheduleValue = "div[data-testid='"; +const destinationPrefix = "input[data-testid='prefixInput']"; +const replicationTab = "div[data-id='replication-step']"; +const destinationNamespace = "div[data-testid='namespaceDefinition']"; +const destinationNamespaceCustom = "div[data-testid='namespaceDefinition-customformat']"; +const destinationNamespaceCustomInput = "input[data-testid='input']"; +const syncModeDropdown = "div.sc-lbxAil.hgSxej"; +const syncModeFullAppendValue = "div.sc-ftvSup.sc-jDDxOa.sEMqZ.kVUvAu"; +const successResult = "span[data-id='success-result']"; +const saveChangesButton = "button[type=submit]"; +const saveStreamChangesButton = "button[data-testid='resetModal-save']"; + +export const goToReplicationTab = () => { + cy.get(replicationTab).click(); +} + +export const selectSchedule = (value: string) => { + cy.get(scheduleDropdown).click(); + cy.get(scheduleValue + value + "']").click(); +} + +export const fillOutDestinationPrefix = (value: string) => { + cy.get(destinationPrefix).clear().type(value).should('have.value', value);; +} + +export const setupDestinationNamespaceCustomFormat = (value: string) => { + cy.get(destinationNamespace).click(); + cy.get(destinationNamespaceCustom).click(); + cy.get(destinationNamespaceCustomInput).first().type(value).should('have.value', '${SOURCE_NAMESPACE}' + value); +} + +export const selectFullAppendSyncMode = () => { + cy.get(syncModeDropdown).click(); + cy.get(syncModeFullAppendValue).click(); +} + +export const checkSuccessResult = () => { + cy.get(successResult).should("exist"); +} + +export const clickSaveChanges = () => { + cy.get(saveChangesButton).first().click(); +} + +export const confirmStreamConfigurationChangedPopup = () => { + cy.get(saveStreamChangesButton).click(); +} diff --git a/airbyte-webapp-e2e-tests/cypress/pages/sourcePage.ts b/airbyte-webapp-e2e-tests/cypress/pages/sourcePage.ts new file mode 100644 index 0000000000000..df07dca052072 --- /dev/null +++ b/airbyte-webapp-e2e-tests/cypress/pages/sourcePage.ts @@ -0,0 +1,7 @@ +export const goToSourcePage = () => { + cy.visit("/source"); +} + +export const openSourceDestinationFromGrid = (value: string) => { + cy.get("div").contains(value).click(); +} From ada660af02b27e745a08bc0d56aec6ec9c591fa6 Mon Sep 17 00:00:00 2001 From: Sofiia Zaitseva <108751383+SofiiaZaitseva@users.noreply.github.com> Date: Wed, 24 Aug 2022 15:35:09 +0300 Subject: [PATCH 04/11] change structure with using POM --- .../cypress/commands/common.ts | 40 -------------- .../cypress/commands/connection.ts | 24 ++++----- .../cypress/commands/connector.ts | 42 +++++++++++++++ .../cypress/commands/destination.ts | 12 +++-- .../cypress/commands/sidebar.ts | 3 -- .../cypress/commands/source.ts | 54 +++++-------------- .../cypress/integration/connection.spec.ts | 50 +++++++++-------- .../cypress/integration/destination.spec.ts | 8 +-- .../cypress/integration/onboarding.spec.ts | 3 +- .../cypress/integration/source.spec.ts | 8 +-- .../cypress/pages/createConnectorPage.ts | 48 +++++++++++++++++ .../cypress/pages/destinationPage.ts | 18 +++++++ .../cypress/pages/onboaardingPage.ts | 5 ++ .../cypress/pages/replicationPage.ts | 16 ++++-- .../cypress/pages/settingsConnectionPage.ts | 5 ++ .../cypress/pages/sidebar.ts | 5 ++ .../cypress/pages/sourcePage.ts | 10 ++++ 17 files changed, 217 insertions(+), 134 deletions(-) create mode 100644 airbyte-webapp-e2e-tests/cypress/commands/connector.ts delete mode 100644 airbyte-webapp-e2e-tests/cypress/commands/sidebar.ts create mode 100644 airbyte-webapp-e2e-tests/cypress/pages/createConnectorPage.ts create mode 100644 airbyte-webapp-e2e-tests/cypress/pages/destinationPage.ts create mode 100644 airbyte-webapp-e2e-tests/cypress/pages/onboaardingPage.ts create mode 100644 airbyte-webapp-e2e-tests/cypress/pages/settingsConnectionPage.ts create mode 100644 airbyte-webapp-e2e-tests/cypress/pages/sidebar.ts diff --git a/airbyte-webapp-e2e-tests/cypress/commands/common.ts b/airbyte-webapp-e2e-tests/cypress/commands/common.ts index 54ba9001a2c78..902677bccd290 100644 --- a/airbyte-webapp-e2e-tests/cypress/commands/common.ts +++ b/airbyte-webapp-e2e-tests/cypress/commands/common.ts @@ -2,46 +2,6 @@ export const submitButtonClick = () => { cy.get("button[type=submit]").click(); } -export const fillEmail = (email: string) => { - cy.get("input[name=email]").type(email); -} - -export const fillTestLocalJsonForm = (name: string) => { - cy.intercept("/api/v1/destination_definition_specifications/get").as("getDestinationSpecifications"); - - cy.get("div[data-testid='serviceType']").click(); - cy.get("div").contains("Local JSON").click(); - - cy.wait("@getDestinationSpecifications"); - - cy.get("input[name=name]").clear().type(name); - cy.get("input[name='connectionConfiguration.destination_path']").type("/local"); -} - -export const openSourcePage = () => { - cy.intercept("/api/v1/sources/list").as("getSourcesList"); - cy.visit("/source"); - cy.wait("@getSourcesList"); -} - -export const openDestinationPage = () => { - cy.intercept("/api/v1/destinations/list").as("getDestinationsList"); - cy.visit("/destination"); - cy.wait("@getDestinationsList"); -} - -export const openNewSourceForm = () => { - openSourcePage(); - cy.get("button[data-id='new-source'").click(); - cy.url().should("include", `/source/new-source`); -} - -export const openNewDestinationForm = () => { - openDestinationPage(); - cy.get("button[data-id='new-destination'").click(); - cy.url().should("include", `/destination/new-destination`); -} - export const updateField = (field: string, value: string) => { cy.get("input[name='" + field + "']").clear().type(value); } diff --git a/airbyte-webapp-e2e-tests/cypress/commands/connection.ts b/airbyte-webapp-e2e-tests/cypress/commands/connection.ts index 9219ba815acb2..7043b4235344b 100644 --- a/airbyte-webapp-e2e-tests/cypress/commands/connection.ts +++ b/airbyte-webapp-e2e-tests/cypress/commands/connection.ts @@ -1,6 +1,8 @@ import { submitButtonClick } from "./common"; -import { createTestDestination } from "./destination"; -import { createPokeTestSource, createTestSource } from "./source"; +import { createLocalJsonDestination } from "./destination"; +import { createPokeTestSource, createPostgresSource } from "./source"; +import { openAddSource } from "pages/destinationPage" +import { selectSchedule, setupDestinationNamespaceSourceFormat, enterConnectionName } from "pages/replicationPage" export const createTestConnection = (sourceName: string, destinationName: string) => { cy.intercept("/api/v1/sources/discover_schema").as("discoverSchema"); @@ -8,29 +10,27 @@ export const createTestConnection = (sourceName: string, destinationName: string switch (true) { case sourceName.includes('PokeAPI'): - createPokeTestSource(sourceName) + createPokeTestSource(sourceName, "luxray") break; case sourceName.includes('Postgres'): - createTestSource(sourceName); + createPostgresSource(sourceName, "localhost", "{selectAll}{del}5433", "airbyte_ci", "postgres", "secret_password"); break; default: - createTestSource(sourceName); + createPostgresSource(sourceName, "localhost", "{selectAll}{del}5433", "airbyte_ci", "postgres", "secret_password"); } - createTestDestination(destinationName); + createLocalJsonDestination(destinationName, "/local"); cy.wait(5000); - cy.get("div[data-testid='select-source']").click(); + openAddSource(); cy.get("div").contains(sourceName).click(); cy.wait("@discoverSchema"); - cy.get("input[data-testid='connectionName']").type("Connection name"); - cy.get("div[data-testid='scheduleData.basicSchedule']").click(); - cy.get("div[data-testid='Manual']").click(); + enterConnectionName("Connection name"); + selectSchedule("Manual"); - cy.get("div[data-testid='namespaceDefinition']").click(); - cy.get("div[data-testid='namespaceDefinition-source']").click(); + setupDestinationNamespaceSourceFormat(); submitButtonClick(); cy.wait("@createConnection"); diff --git a/airbyte-webapp-e2e-tests/cypress/commands/connector.ts b/airbyte-webapp-e2e-tests/cypress/commands/connector.ts new file mode 100644 index 0000000000000..c3169ee2a5b5f --- /dev/null +++ b/airbyte-webapp-e2e-tests/cypress/commands/connector.ts @@ -0,0 +1,42 @@ +import { enterDestinationPath, selectServiceType, enterName, enterHost, enterPort, enterDatabase, enterUsername, enterPassword, enterPokeName } from "pages/createConnectorPage" + +export const fillPostgresForm = (name: string, host: string, port: string, database: string, username: string, password: string) => { + cy.intercept("/api/v1/source_definition_specifications/get").as( + "getSourceSpecifications" + ); + + selectServiceType("Postgres"); + + cy.wait("@getSourceSpecifications"); + + enterName(name); + enterHost(host); + enterPort(port); + enterDatabase(database); + enterUsername(username); + enterPassword(password); +}; + +export const fillPokeAPIForm = (name: string, pokeName: string) => { + cy.intercept("/api/v1/source_definition_specifications/get").as( + "getSourceSpecifications" + ); + + selectServiceType("PokeAPI"); + + cy.wait("@getSourceSpecifications"); + + enterName(name); + enterPokeName(pokeName); +}; + +export const fillLocalJsonForm = (name: string, destinationPath: string) => { + cy.intercept("/api/v1/destination_definition_specifications/get").as("getDestinationSpecifications"); + + selectServiceType("Local JSON"); + + cy.wait("@getDestinationSpecifications"); + + enterName(name); + enterDestinationPath(destinationPath); +} \ No newline at end of file diff --git a/airbyte-webapp-e2e-tests/cypress/commands/destination.ts b/airbyte-webapp-e2e-tests/cypress/commands/destination.ts index a3a6f5514cfd9..c824316bdd388 100644 --- a/airbyte-webapp-e2e-tests/cypress/commands/destination.ts +++ b/airbyte-webapp-e2e-tests/cypress/commands/destination.ts @@ -1,13 +1,17 @@ -import { deleteEntity, fillTestLocalJsonForm, openDestinationPage, openNewDestinationForm, openSettingForm, submitButtonClick, updateField } from "./common"; +import { deleteEntity, openSettingForm, submitButtonClick, updateField } from "./common"; +import { fillLocalJsonForm } from "./connector" +import { openDestinationPage, openNewDestinationForm } from "pages/destinationPage" -export const createTestDestination = (name: string) => { +export const createLocalJsonDestination = (name: string, destinationPath: string) => { cy.intercept("/api/v1/scheduler/destinations/check_connection").as("checkDestinationConnection"); cy.intercept("/api/v1/destinations/create").as("createDestination"); + openDestinationPage(); openNewDestinationForm(); - fillTestLocalJsonForm(name); + fillLocalJsonForm(name, destinationPath); submitButtonClick(); + cy.wait(3000); cy.wait("@checkDestinationConnection"); cy.wait("@createDestination"); } @@ -26,7 +30,9 @@ export const updateDestination = (name: string, field: string, value: string) => } export const deleteDestination = (name: string) => { + cy.intercept("/api/v1/destinations/delete").as("deleteDestination"); openDestinationPage(); openSettingForm(name); deleteEntity(); + cy.wait("@deleteDestination"); } \ No newline at end of file diff --git a/airbyte-webapp-e2e-tests/cypress/commands/sidebar.ts b/airbyte-webapp-e2e-tests/cypress/commands/sidebar.ts deleted file mode 100644 index 2b4f52015fbf0..0000000000000 --- a/airbyte-webapp-e2e-tests/cypress/commands/sidebar.ts +++ /dev/null @@ -1,3 +0,0 @@ -export const openSettings = () => { - cy.get("nav a[href*='settings']").click(); -}; diff --git a/airbyte-webapp-e2e-tests/cypress/commands/source.ts b/airbyte-webapp-e2e-tests/cypress/commands/source.ts index f5e14f2163163..7a52ad9f1b5e9 100644 --- a/airbyte-webapp-e2e-tests/cypress/commands/source.ts +++ b/airbyte-webapp-e2e-tests/cypress/commands/source.ts @@ -1,61 +1,31 @@ -import { deleteEntity, openNewSourceForm, openSettingForm, openSourcePage, submitButtonClick, updateField } from "./common"; +import { deleteEntity, openSettingForm, submitButtonClick, updateField } from "./common"; +import { goToSourcePage, openNewSourceForm} from "pages/sourcePage"; +import { fillPostgresForm, fillPokeAPIForm } from "./connector" -export const fillPgSourceForm = (name: string) => { - cy.intercept("/api/v1/source_definition_specifications/get").as( - "getSourceSpecifications" - ); - - cy.get("div[data-testid='serviceType']").click(); - cy.get("div").contains("Postgres").click(); - - cy.wait("@getSourceSpecifications"); - - cy.get("input[name=name]").clear().type(name); - cy.get("input[name='connectionConfiguration.host']").type("localhost"); - cy.get("input[name='connectionConfiguration.port']").type("{selectAll}{del}5433"); - cy.get("input[name='connectionConfiguration.database']").type("airbyte_ci"); - cy.get("input[name='connectionConfiguration.username']").type("postgres"); - cy.get("input[name='connectionConfiguration.password']").type( - "secret_password" - ); -}; - -export const fillPokeAPISourceForm = (name: string) => { - cy.intercept("/api/v1/source_definition_specifications/get").as( - "getSourceSpecifications" - ); - - cy.get("div[data-testid='serviceType']").click(); - cy.get("div").contains("PokeAPI").click(); - - cy.wait("@getSourceSpecifications"); - - cy.get("input[name=name]").clear().type(name); - cy.get("input[name='connectionConfiguration.pokemon_name']").type("luxray"); -}; - -export const createTestSource = (name: string) => { +export const createPostgresSource = (name: string, host: string, port: string, database: string, username: string, password: string) => { cy.intercept("/api/v1/scheduler/sources/check_connection").as( "checkSourceUpdateConnection" ); cy.intercept("/api/v1/sources/create").as("createSource"); + goToSourcePage(); openNewSourceForm(); - fillPgSourceForm(name); + fillPostgresForm(name, host, port, database, username, password); submitButtonClick(); cy.wait("@checkSourceUpdateConnection"); cy.wait("@createSource"); }; -export const createPokeTestSource = (name: string) => { +export const createPokeTestSource = (name: string, pokeName: string) => { cy.intercept("/api/v1/scheduler/sources/check_connection").as( "checkSourceUpdateConnection" ); cy.intercept("/api/v1/sources/create").as("createSource"); + goToSourcePage(); openNewSourceForm(); - fillPokeAPISourceForm(name); + fillPokeAPIForm(name, pokeName); submitButtonClick(); cy.wait("@checkSourceUpdateConnection"); @@ -68,7 +38,7 @@ export const updateSource = (name: string, field: string, value: string) => { ); cy.intercept("/api/v1/sources/update").as("updateSource"); - openSourcePage(); + goToSourcePage(); openSettingForm(name); updateField(field, value); submitButtonClick(); @@ -78,7 +48,9 @@ export const updateSource = (name: string, field: string, value: string) => { } export const deleteSource = (name: string) => { - openSourcePage(); + cy.intercept("/api/v1/sources/delete").as("deleteSource"); + goToSourcePage(); openSettingForm(name); deleteEntity(); + cy.wait("@deleteSource"); } diff --git a/airbyte-webapp-e2e-tests/cypress/integration/connection.spec.ts b/airbyte-webapp-e2e-tests/cypress/integration/connection.spec.ts index b4ce35889c3c4..830d8fa017356 100644 --- a/airbyte-webapp-e2e-tests/cypress/integration/connection.spec.ts +++ b/airbyte-webapp-e2e-tests/cypress/integration/connection.spec.ts @@ -1,10 +1,11 @@ -import { deleteEntity } from "commands/common"; +import { deleteEntity, submitButtonClick } from "commands/common"; import { createTestConnection } from "commands/connection"; import { deleteDestination } from "commands/destination"; import { deleteSource } from "commands/source"; import { initialSetupCompleted } from "commands/workspaces"; -import { confirmStreamConfigurationChangedPopup, clickSaveChanges, selectSchedule, fillOutDestinationPrefix, goToReplicationTab, setupDestinationNamespaceCustomFormat, selectFullAppendSyncMode, checkSuccessResult} from "pages/replicationPage"; +import { confirmStreamConfigurationChangedPopup, selectSchedule, fillOutDestinationPrefix, goToReplicationTab, setupDestinationNamespaceCustomFormat, selectFullAppendSyncMode, checkSuccessResult} from "pages/replicationPage"; import { openSourceDestinationFromGrid, goToSourcePage} from "pages/sourcePage"; +import { goToSettingsPage } from "pages/settingsConnectionPage" describe("Connection main actions", () => { beforeEach(() => { @@ -12,10 +13,13 @@ describe("Connection main actions", () => { }); it("Create new connection", () => { - createTestConnection("Test connection source cypress", "Test destination cypress"); + createTestConnection("Test connection source cypress", "Test connection destination cypress"); cy.get("div").contains("Test connection source cypress").should("exist"); - cy.get("div").contains("Test destination cypress").should("exist"); + cy.get("div").contains("Test connection destination cypress").should("exist"); + + deleteSource("Test connection source cypress"); + deleteDestination("Test connection destination cypress"); }); it("Update connection", () => { @@ -23,23 +27,24 @@ describe("Connection main actions", () => { createTestConnection("Test update connection source cypress", "Test update connection destination cypress"); - cy.visit("/source"); - cy.get("div").contains("Test update connection source cypress").click(); - cy.get("div").contains("Test update connection destination cypress").click(); + goToSourcePage(); + openSourceDestinationFromGrid("Test update connection source cypress"); + openSourceDestinationFromGrid("Test update connection destination cypress"); - cy.get("div[data-id='replication-step']").click(); + goToReplicationTab(); + + selectSchedule('Every hour'); + fillOutDestinationPrefix('auto_test'); - cy.get("div[data-testid='scheduleData.basicSchedule']").click(); - cy.get("div[data-testid='Every hour']").click(); - cy.get("input[data-testid='prefixInput']").clear(); - cy.get("input[data-testid='prefixInput']").type('auto_test'); - cy.get("button[type=submit]").first().click(); + submitButtonClick(); cy.wait("@updateConnection").then((interception) => { - assert.isNotNull(interception.response?.statusCode, '200'); - cy.get("span[data-id='success-result']").should("exist"); + assert.isNotNull(interception.response?.statusCode, '200'); + }); + checkSuccessResult(); - }) + deleteSource("Test update connection source cypress"); + deleteDestination("Test update connection destination cypress"); }); it("Update connection (pokeAPI)", () => { @@ -60,7 +65,7 @@ describe("Connection main actions", () => { setupDestinationNamespaceCustomFormat('_test'); selectFullAppendSyncMode(); - clickSaveChanges(); + submitButtonClick(); confirmStreamConfigurationChangedPopup(); cy.wait("@updateConnection").then((interception) => { @@ -92,16 +97,19 @@ describe("Connection main actions", () => { ); }) checkSuccessResult(); + + deleteSource("Test update connection PokeAPI source cypress"); + deleteDestination("Test update connection Local JSON destination cypress"); }); it("Delete connection", () => { createTestConnection("Test delete connection source cypress", "Test delete connection destination cypress"); - cy.visit("/source"); - cy.get("div").contains("Test delete connection source cypress").click(); - cy.get("div").contains("Test delete connection destination cypress").click(); + goToSourcePage(); + openSourceDestinationFromGrid("Test delete connection source cypress"); + openSourceDestinationFromGrid("Test delete connection destination cypress"); - cy.get("div[data-id='settings-step']").click(); + goToSettingsPage(); deleteEntity(); diff --git a/airbyte-webapp-e2e-tests/cypress/integration/destination.spec.ts b/airbyte-webapp-e2e-tests/cypress/integration/destination.spec.ts index 5b25066f70d09..a7dbe94c66f57 100644 --- a/airbyte-webapp-e2e-tests/cypress/integration/destination.spec.ts +++ b/airbyte-webapp-e2e-tests/cypress/integration/destination.spec.ts @@ -1,4 +1,4 @@ -import { createTestDestination, deleteDestination, updateDestination } from "commands/destination"; +import { createLocalJsonDestination, deleteDestination, updateDestination } from "commands/destination"; import { initialSetupCompleted } from "commands/workspaces"; describe("Destination main actions", () => { @@ -7,13 +7,13 @@ describe("Destination main actions", () => { }); it("Create new destination", () => { - createTestDestination("Test destination cypress"); + createLocalJsonDestination("Test destination cypress", "/local"); cy.url().should("include", `/destination/`); }); it("Update destination", () => { - createTestDestination("Test destination cypress for update"); + createLocalJsonDestination("Test destination cypress for update", "/local"); updateDestination("Test destination cypress for update", "connectionConfiguration.destination_path", "/local/my-json"); cy.get("div[data-id='success-result']").should("exist"); @@ -21,7 +21,7 @@ describe("Destination main actions", () => { }); it("Delete destination", () => { - createTestDestination("Test destination cypress for delete"); + createLocalJsonDestination("Test destination cypress for delete", "/local"); deleteDestination("Test destination cypress for delete"); cy.visit("/destination"); diff --git a/airbyte-webapp-e2e-tests/cypress/integration/onboarding.spec.ts b/airbyte-webapp-e2e-tests/cypress/integration/onboarding.spec.ts index a5fea357d4a86..b8cb6f97040a5 100644 --- a/airbyte-webapp-e2e-tests/cypress/integration/onboarding.spec.ts +++ b/airbyte-webapp-e2e-tests/cypress/integration/onboarding.spec.ts @@ -1,5 +1,6 @@ -import { fillEmail, submitButtonClick } from "commands/common"; +import { submitButtonClick } from "commands/common"; import { initialSetupCompleted } from "commands/workspaces"; +import { fillEmail } from "pages/onboaardingPage"; describe("Preferences actions", () => { beforeEach(() => { diff --git a/airbyte-webapp-e2e-tests/cypress/integration/source.spec.ts b/airbyte-webapp-e2e-tests/cypress/integration/source.spec.ts index 8f532ed109212..6e8882c2fdae3 100644 --- a/airbyte-webapp-e2e-tests/cypress/integration/source.spec.ts +++ b/airbyte-webapp-e2e-tests/cypress/integration/source.spec.ts @@ -1,4 +1,4 @@ -import { createTestSource, deleteSource, updateSource } from "commands/source"; +import { createPostgresSource, deleteSource, updateSource } from "commands/source"; import { initialSetupCompleted } from "commands/workspaces"; describe("Source main actions", () => { @@ -7,14 +7,14 @@ describe("Source main actions", () => { }); it("Create new source", () => { - createTestSource("Test source cypress"); + createPostgresSource("Test source cypress", "localhost", "{selectAll}{del}5433", "airbyte_ci", "postgres", "secret_password"); cy.url().should("include", `/source/`); }); //TODO: add update source on some other connector or create 1 more user for pg it.skip("Update source", () => { - createTestSource("Test source cypress for update"); + createPostgresSource("Test source cypress for update", "localhost", "{selectAll}{del}5433", "airbyte_ci", "postgres", "secret_password"); updateSource("Test source cypress for update", "connectionConfiguration.start_date", "2020-11-11"); cy.get("div[data-id='success-result']").should("exist"); @@ -22,7 +22,7 @@ describe("Source main actions", () => { }); it("Delete source", () => { - createTestSource("Test source cypress for delete"); + createPostgresSource("Test source cypress for delete", "localhost", "{selectAll}{del}5433", "airbyte_ci", "postgres", "secret_password"); deleteSource("Test source cypress for delete"); cy.visit("/"); diff --git a/airbyte-webapp-e2e-tests/cypress/pages/createConnectorPage.ts b/airbyte-webapp-e2e-tests/cypress/pages/createConnectorPage.ts new file mode 100644 index 0000000000000..4d6bf3d321f91 --- /dev/null +++ b/airbyte-webapp-e2e-tests/cypress/pages/createConnectorPage.ts @@ -0,0 +1,48 @@ +const selectTypeDropdown = "div[data-testid='serviceType']"; +const nameInput = "input[name=name]"; +const hostInput = "input[name='connectionConfiguration.host']"; +const portInput = "input[name='connectionConfiguration.port']"; +const databaseInput = "input[name='connectionConfiguration.database']"; +const usernameInput = "input[name='connectionConfiguration.username']"; +const passwordInput = "input[name='connectionConfiguration.password']"; +const pokeNameInput = "input[name='connectionConfiguration.pokemon_name']"; +const destinationPathInput = "input[name='connectionConfiguration.destination_path']"; + +export const selectServiceType = (type: string) => { + cy.get(selectTypeDropdown).click(); + cy.get("div").contains(type).click(); +} + +export const enterName = (name: string) => { + cy.get(nameInput).clear().type(name); +} + +export const enterHost = (host: string) => { + cy.get(hostInput).type(host); +} + +export const enterPort = (port: string) => { + cy.get(portInput).type(port); +} + +export const enterDatabase = (database: string) => { + cy.get(databaseInput).type(database); +} + +export const enterUsername = (username: string) => { + cy.get(usernameInput).type(username); +} + +export const enterPassword = (password: string) => { + cy.get(passwordInput).type(password); +} + +export const enterPokeName = (pokeName: string) => { + cy.get(pokeNameInput).type(pokeName); +} + +export const enterDestinationPath = (destinationPath: string) => { + cy.get(destinationPathInput).type(destinationPath); + +} + diff --git a/airbyte-webapp-e2e-tests/cypress/pages/destinationPage.ts b/airbyte-webapp-e2e-tests/cypress/pages/destinationPage.ts new file mode 100644 index 0000000000000..62538a931baec --- /dev/null +++ b/airbyte-webapp-e2e-tests/cypress/pages/destinationPage.ts @@ -0,0 +1,18 @@ +const newDestination = "button[data-id='new-destination'"; +const addSourceButton = "div[data-testid='select-source']"; + +export const openDestinationPage = () => { + cy.intercept("/api/v1/destinations/list").as("getDestinationsList"); + cy.visit("/destination"); + cy.wait(3000); + cy.wait("@getDestinationsList"); + } + + export const openNewDestinationForm = () => { + cy.get(newDestination).click(); + cy.url().should("include", `/destination/new-destination`); + } + + export const openAddSource = () => { + cy.get(addSourceButton).click(); + } \ No newline at end of file diff --git a/airbyte-webapp-e2e-tests/cypress/pages/onboaardingPage.ts b/airbyte-webapp-e2e-tests/cypress/pages/onboaardingPage.ts new file mode 100644 index 0000000000000..9d462824355bd --- /dev/null +++ b/airbyte-webapp-e2e-tests/cypress/pages/onboaardingPage.ts @@ -0,0 +1,5 @@ +const emailInput = "input[name=email]"; + +export const fillEmail = (email: string) => { + cy.get(emailInput).type(email); +} \ No newline at end of file diff --git a/airbyte-webapp-e2e-tests/cypress/pages/replicationPage.ts b/airbyte-webapp-e2e-tests/cypress/pages/replicationPage.ts index 9b340e006c54f..18e219a49d221 100644 --- a/airbyte-webapp-e2e-tests/cypress/pages/replicationPage.ts +++ b/airbyte-webapp-e2e-tests/cypress/pages/replicationPage.ts @@ -4,17 +4,22 @@ const destinationPrefix = "input[data-testid='prefixInput']"; const replicationTab = "div[data-id='replication-step']"; const destinationNamespace = "div[data-testid='namespaceDefinition']"; const destinationNamespaceCustom = "div[data-testid='namespaceDefinition-customformat']"; +const destinationNamespaceSource = "div[data-testid='namespaceDefinition-source']"; const destinationNamespaceCustomInput = "input[data-testid='input']"; const syncModeDropdown = "div.sc-lbxAil.hgSxej"; const syncModeFullAppendValue = "div.sc-ftvSup.sc-jDDxOa.sEMqZ.kVUvAu"; const successResult = "span[data-id='success-result']"; -const saveChangesButton = "button[type=submit]"; const saveStreamChangesButton = "button[data-testid='resetModal-save']"; +const connectionNameInput = "input[data-testid='connectionName']"; export const goToReplicationTab = () => { cy.get(replicationTab).click(); } +export const enterConnectionName = (name: string) => { + cy.get(connectionNameInput).type(name); +} + export const selectSchedule = (value: string) => { cy.get(scheduleDropdown).click(); cy.get(scheduleValue + value + "']").click(); @@ -30,6 +35,11 @@ export const setupDestinationNamespaceCustomFormat = (value: string) => { cy.get(destinationNamespaceCustomInput).first().type(value).should('have.value', '${SOURCE_NAMESPACE}' + value); } +export const setupDestinationNamespaceSourceFormat = () => { + cy.get(destinationNamespace).click(); + cy.get(destinationNamespaceSource).click(); +} + export const selectFullAppendSyncMode = () => { cy.get(syncModeDropdown).click(); cy.get(syncModeFullAppendValue).click(); @@ -39,10 +49,6 @@ export const checkSuccessResult = () => { cy.get(successResult).should("exist"); } -export const clickSaveChanges = () => { - cy.get(saveChangesButton).first().click(); -} - export const confirmStreamConfigurationChangedPopup = () => { cy.get(saveStreamChangesButton).click(); } diff --git a/airbyte-webapp-e2e-tests/cypress/pages/settingsConnectionPage.ts b/airbyte-webapp-e2e-tests/cypress/pages/settingsConnectionPage.ts new file mode 100644 index 0000000000000..283659169d7b4 --- /dev/null +++ b/airbyte-webapp-e2e-tests/cypress/pages/settingsConnectionPage.ts @@ -0,0 +1,5 @@ +const settingsTab = "div[data-id='settings-step']"; + +export const goToSettingsPage = () => { + cy.get(settingsTab).click(); +} diff --git a/airbyte-webapp-e2e-tests/cypress/pages/sidebar.ts b/airbyte-webapp-e2e-tests/cypress/pages/sidebar.ts new file mode 100644 index 0000000000000..31ff3cb2742f4 --- /dev/null +++ b/airbyte-webapp-e2e-tests/cypress/pages/sidebar.ts @@ -0,0 +1,5 @@ +const setting = "nav a[href*='settings']"; + +export const openSettings = () => { + cy.get(setting).click(); +}; diff --git a/airbyte-webapp-e2e-tests/cypress/pages/sourcePage.ts b/airbyte-webapp-e2e-tests/cypress/pages/sourcePage.ts index df07dca052072..dcd2719c6965a 100644 --- a/airbyte-webapp-e2e-tests/cypress/pages/sourcePage.ts +++ b/airbyte-webapp-e2e-tests/cypress/pages/sourcePage.ts @@ -1,7 +1,17 @@ +const newSource = "button[data-id='new-source'"; + export const goToSourcePage = () => { + cy.intercept("/api/v1/sources/list").as("getSourcesList"); cy.visit("/source"); + cy.wait(3000); + cy.wait("@getSourcesList"); } export const openSourceDestinationFromGrid = (value: string) => { cy.get("div").contains(value).click(); } + +export const openNewSourceForm = () => { + cy.get(newSource).click(); + cy.url().should("include", `/source/new-source`); + } From 2a41523989e22c2016a339595a1ca5f77acf9709 Mon Sep 17 00:00:00 2001 From: Alex Birdsall Date: Mon, 29 Aug 2022 07:48:21 -0700 Subject: [PATCH 05/11] Select sync mode dropdown with a data-testid (#16053) --- .../cypress/pages/replicationPage.ts | 12 +++++++----- .../CatalogTree/components/SyncSettingsDropdown.tsx | 1 + 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/airbyte-webapp-e2e-tests/cypress/pages/replicationPage.ts b/airbyte-webapp-e2e-tests/cypress/pages/replicationPage.ts index 18e219a49d221..708aa7dff14e4 100644 --- a/airbyte-webapp-e2e-tests/cypress/pages/replicationPage.ts +++ b/airbyte-webapp-e2e-tests/cypress/pages/replicationPage.ts @@ -6,8 +6,7 @@ const destinationNamespace = "div[data-testid='namespaceDefinition']"; const destinationNamespaceCustom = "div[data-testid='namespaceDefinition-customformat']"; const destinationNamespaceSource = "div[data-testid='namespaceDefinition-source']"; const destinationNamespaceCustomInput = "input[data-testid='input']"; -const syncModeDropdown = "div.sc-lbxAil.hgSxej"; -const syncModeFullAppendValue = "div.sc-ftvSup.sc-jDDxOa.sEMqZ.kVUvAu"; +const syncModeDropdown = "div[data-testid='syncSettingsDropdown'] input"; const successResult = "span[data-id='success-result']"; const saveStreamChangesButton = "button[data-testid='resetModal-save']"; const connectionNameInput = "input[data-testid='connectionName']"; @@ -41,9 +40,12 @@ export const setupDestinationNamespaceSourceFormat = () => { } export const selectFullAppendSyncMode = () => { - cy.get(syncModeDropdown).click(); - cy.get(syncModeFullAppendValue).click(); -} + cy.get(syncModeDropdown).first().click({ force: true }); + + cy.get(`.react-select__menu`) + .contains("Append") // it would be nice to select for "Full refresh" is there too + .click(); +}; export const checkSuccessResult = () => { cy.get(successResult).should("exist"); diff --git a/airbyte-webapp/src/views/Connection/CatalogTree/components/SyncSettingsDropdown.tsx b/airbyte-webapp/src/views/Connection/CatalogTree/components/SyncSettingsDropdown.tsx index e435b8ca7c8f7..f19ade854af6f 100644 --- a/airbyte-webapp/src/views/Connection/CatalogTree/components/SyncSettingsDropdown.tsx +++ b/airbyte-webapp/src/views/Connection/CatalogTree/components/SyncSettingsDropdown.tsx @@ -106,6 +106,7 @@ const SyncSettingsDropdown: React.FC = (props) => ( Option, Control: DropdownControl, }} + data-testid="syncSettingsDropdown" $withBorder /> ); From 1546e3a63a5f72feb490c7256ce92865f57200ad Mon Sep 17 00:00:00 2001 From: Sofiia Zaitseva <108751383+SofiiaZaitseva@users.noreply.github.com> Date: Thu, 1 Sep 2022 16:45:27 +0300 Subject: [PATCH 06/11] Fix coments --- .../cypress/commands/connection.ts | 8 ++++---- .../cypress/commands/connector.ts | 4 ++-- .../cypress/commands/destination.ts | 8 ++++---- airbyte-webapp-e2e-tests/cypress/commands/source.ts | 11 +++++++++-- .../cypress/integration/connection.spec.ts | 10 ++++++---- .../cypress/integration/onboarding.spec.ts | 3 +-- .../cypress/integration/source.spec.ts | 6 +++--- .../cypress/pages/createConnectorPage.ts | 6 +++--- .../cypress/pages/onboaardingPage.ts | 5 ----- .../cypress/pages/replicationPage.ts | 4 ++-- 10 files changed, 34 insertions(+), 31 deletions(-) delete mode 100644 airbyte-webapp-e2e-tests/cypress/pages/onboaardingPage.ts diff --git a/airbyte-webapp-e2e-tests/cypress/commands/connection.ts b/airbyte-webapp-e2e-tests/cypress/commands/connection.ts index 7043b4235344b..55e8493a5c7b2 100644 --- a/airbyte-webapp-e2e-tests/cypress/commands/connection.ts +++ b/airbyte-webapp-e2e-tests/cypress/commands/connection.ts @@ -1,6 +1,6 @@ import { submitButtonClick } from "./common"; import { createLocalJsonDestination } from "./destination"; -import { createPokeTestSource, createPostgresSource } from "./source"; +import { createPokeApiSource, createPostgresSource } from "./source"; import { openAddSource } from "pages/destinationPage" import { selectSchedule, setupDestinationNamespaceSourceFormat, enterConnectionName } from "pages/replicationPage" @@ -10,13 +10,13 @@ export const createTestConnection = (sourceName: string, destinationName: string switch (true) { case sourceName.includes('PokeAPI'): - createPokeTestSource(sourceName, "luxray") + createPokeApiSource(sourceName, "luxray") break; case sourceName.includes('Postgres'): - createPostgresSource(sourceName, "localhost", "{selectAll}{del}5433", "airbyte_ci", "postgres", "secret_password"); + createPostgresSource(sourceName); break; default: - createPostgresSource(sourceName, "localhost", "{selectAll}{del}5433", "airbyte_ci", "postgres", "secret_password"); + createPostgresSource(sourceName); } createLocalJsonDestination(destinationName, "/local"); diff --git a/airbyte-webapp-e2e-tests/cypress/commands/connector.ts b/airbyte-webapp-e2e-tests/cypress/commands/connector.ts index c3169ee2a5b5f..8abb5fbd12b0d 100644 --- a/airbyte-webapp-e2e-tests/cypress/commands/connector.ts +++ b/airbyte-webapp-e2e-tests/cypress/commands/connector.ts @@ -1,4 +1,4 @@ -import { enterDestinationPath, selectServiceType, enterName, enterHost, enterPort, enterDatabase, enterUsername, enterPassword, enterPokeName } from "pages/createConnectorPage" +import { enterDestinationPath, selectServiceType, enterName, enterHost, enterPort, enterDatabase, enterUsername, enterPassword, enterPokemonName } from "pages/createConnectorPage" export const fillPostgresForm = (name: string, host: string, port: string, database: string, username: string, password: string) => { cy.intercept("/api/v1/source_definition_specifications/get").as( @@ -27,7 +27,7 @@ export const fillPokeAPIForm = (name: string, pokeName: string) => { cy.wait("@getSourceSpecifications"); enterName(name); - enterPokeName(pokeName); + enterPokemonName(pokeName); }; export const fillLocalJsonForm = (name: string, destinationPath: string) => { diff --git a/airbyte-webapp-e2e-tests/cypress/commands/destination.ts b/airbyte-webapp-e2e-tests/cypress/commands/destination.ts index c824316bdd388..2f3e54a7cfda9 100644 --- a/airbyte-webapp-e2e-tests/cypress/commands/destination.ts +++ b/airbyte-webapp-e2e-tests/cypress/commands/destination.ts @@ -1,12 +1,12 @@ import { deleteEntity, openSettingForm, submitButtonClick, updateField } from "./common"; import { fillLocalJsonForm } from "./connector" -import { openDestinationPage, openNewDestinationForm } from "pages/destinationPage" +import { goToDestinationPage, openNewDestinationForm } from "pages/destinationPage" export const createLocalJsonDestination = (name: string, destinationPath: string) => { cy.intercept("/api/v1/scheduler/destinations/check_connection").as("checkDestinationConnection"); cy.intercept("/api/v1/destinations/create").as("createDestination"); - openDestinationPage(); + goToDestinationPage(); openNewDestinationForm(); fillLocalJsonForm(name, destinationPath); submitButtonClick(); @@ -20,7 +20,7 @@ export const updateDestination = (name: string, field: string, value: string) => cy.intercept("/api/v1/destinations/check_connection_for_update").as("checkDestinationUpdateConnection"); cy.intercept("/api/v1/destinations/update").as("updateDestination"); - openDestinationPage(); + goToDestinationPage(); openSettingForm(name); updateField(field, value); submitButtonClick(); @@ -31,7 +31,7 @@ export const updateDestination = (name: string, field: string, value: string) => export const deleteDestination = (name: string) => { cy.intercept("/api/v1/destinations/delete").as("deleteDestination"); - openDestinationPage(); + goToDestinationPage(); openSettingForm(name); deleteEntity(); cy.wait("@deleteDestination"); diff --git a/airbyte-webapp-e2e-tests/cypress/commands/source.ts b/airbyte-webapp-e2e-tests/cypress/commands/source.ts index 7a52ad9f1b5e9..479627e607dd6 100644 --- a/airbyte-webapp-e2e-tests/cypress/commands/source.ts +++ b/airbyte-webapp-e2e-tests/cypress/commands/source.ts @@ -2,7 +2,14 @@ import { deleteEntity, openSettingForm, submitButtonClick, updateField } from ". import { goToSourcePage, openNewSourceForm} from "pages/sourcePage"; import { fillPostgresForm, fillPokeAPIForm } from "./connector" -export const createPostgresSource = (name: string, host: string, port: string, database: string, username: string, password: string) => { +export const createPostgresSource = ( + name: string, + host: string = "localhost", + port: string = "{selectAll}{del}5433", + database: string = "airbyte_ci", + username: string = "postgres", + password: string = "secret_password" +) => { cy.intercept("/api/v1/scheduler/sources/check_connection").as( "checkSourceUpdateConnection" ); @@ -17,7 +24,7 @@ export const createPostgresSource = (name: string, host: string, port: string, d cy.wait("@createSource"); }; -export const createPokeTestSource = (name: string, pokeName: string) => { +export const createPokeApiSource = (name: string, pokeName: string) => { cy.intercept("/api/v1/scheduler/sources/check_connection").as( "checkSourceUpdateConnection" ); diff --git a/airbyte-webapp-e2e-tests/cypress/integration/connection.spec.ts b/airbyte-webapp-e2e-tests/cypress/integration/connection.spec.ts index 830d8fa017356..8a79c46f5e490 100644 --- a/airbyte-webapp-e2e-tests/cypress/integration/connection.spec.ts +++ b/airbyte-webapp-e2e-tests/cypress/integration/connection.spec.ts @@ -23,7 +23,7 @@ describe("Connection main actions", () => { }); it("Update connection", () => { - cy.intercept("/api/v1/web_backend/connections/update").as("updateConnection"); + cy.intercept("/api/v1/web_backend/connections/updateNew").as("updateConnection"); createTestConnection("Test update connection source cypress", "Test update connection destination cypress"); @@ -83,16 +83,18 @@ describe("Connection main actions", () => { timeUnit: 'minutes' }); - expect(interception.request.body.syncCatalog.streams[0].config).to.contain({ + const streamToUpdate = interception.request.body.syncCatalog.streams[0]; + + expect(streamToUpdate.config).to.contain({ aliasName: 'pokemon', destinationSyncMode: 'append', selected: true, }); - expect(interception.request.body.syncCatalog.streams[0].stream).to.contain({ + expect(streamToUpdate.stream).to.contain({ name: "pokemon", }); - expect(interception.request.body.syncCatalog.streams[0].stream.supportedSyncModes).to.contain( + expect(streamToUpdate.stream.supportedSyncModes).to.contain( 'full_refresh' ); }) diff --git a/airbyte-webapp-e2e-tests/cypress/integration/onboarding.spec.ts b/airbyte-webapp-e2e-tests/cypress/integration/onboarding.spec.ts index b8cb6f97040a5..3e5d5446273f4 100644 --- a/airbyte-webapp-e2e-tests/cypress/integration/onboarding.spec.ts +++ b/airbyte-webapp-e2e-tests/cypress/integration/onboarding.spec.ts @@ -1,6 +1,5 @@ -import { submitButtonClick } from "commands/common"; +import { submitButtonClick, fillEmail } from "commands/common"; import { initialSetupCompleted } from "commands/workspaces"; -import { fillEmail } from "pages/onboaardingPage"; describe("Preferences actions", () => { beforeEach(() => { diff --git a/airbyte-webapp-e2e-tests/cypress/integration/source.spec.ts b/airbyte-webapp-e2e-tests/cypress/integration/source.spec.ts index 6e8882c2fdae3..12bd0f38b206f 100644 --- a/airbyte-webapp-e2e-tests/cypress/integration/source.spec.ts +++ b/airbyte-webapp-e2e-tests/cypress/integration/source.spec.ts @@ -7,14 +7,14 @@ describe("Source main actions", () => { }); it("Create new source", () => { - createPostgresSource("Test source cypress", "localhost", "{selectAll}{del}5433", "airbyte_ci", "postgres", "secret_password"); + createPostgresSource("Test source cypress"); cy.url().should("include", `/source/`); }); //TODO: add update source on some other connector or create 1 more user for pg it.skip("Update source", () => { - createPostgresSource("Test source cypress for update", "localhost", "{selectAll}{del}5433", "airbyte_ci", "postgres", "secret_password"); + createPostgresSource("Test source cypress for update"); updateSource("Test source cypress for update", "connectionConfiguration.start_date", "2020-11-11"); cy.get("div[data-id='success-result']").should("exist"); @@ -22,7 +22,7 @@ describe("Source main actions", () => { }); it("Delete source", () => { - createPostgresSource("Test source cypress for delete", "localhost", "{selectAll}{del}5433", "airbyte_ci", "postgres", "secret_password"); + createPostgresSource("Test source cypress for delete"); deleteSource("Test source cypress for delete"); cy.visit("/"); diff --git a/airbyte-webapp-e2e-tests/cypress/pages/createConnectorPage.ts b/airbyte-webapp-e2e-tests/cypress/pages/createConnectorPage.ts index 4d6bf3d321f91..3915fe3478799 100644 --- a/airbyte-webapp-e2e-tests/cypress/pages/createConnectorPage.ts +++ b/airbyte-webapp-e2e-tests/cypress/pages/createConnectorPage.ts @@ -5,7 +5,7 @@ const portInput = "input[name='connectionConfiguration.port']"; const databaseInput = "input[name='connectionConfiguration.database']"; const usernameInput = "input[name='connectionConfiguration.username']"; const passwordInput = "input[name='connectionConfiguration.password']"; -const pokeNameInput = "input[name='connectionConfiguration.pokemon_name']"; +const pokemonNameInput = "input[name='connectionConfiguration.pokemon_name']"; const destinationPathInput = "input[name='connectionConfiguration.destination_path']"; export const selectServiceType = (type: string) => { @@ -37,8 +37,8 @@ export const enterPassword = (password: string) => { cy.get(passwordInput).type(password); } -export const enterPokeName = (pokeName: string) => { - cy.get(pokeNameInput).type(pokeName); +export const enterPokemonName = (pokeName: string) => { + cy.get(pokemonNameInput).type(pokeName); } export const enterDestinationPath = (destinationPath: string) => { diff --git a/airbyte-webapp-e2e-tests/cypress/pages/onboaardingPage.ts b/airbyte-webapp-e2e-tests/cypress/pages/onboaardingPage.ts deleted file mode 100644 index 9d462824355bd..0000000000000 --- a/airbyte-webapp-e2e-tests/cypress/pages/onboaardingPage.ts +++ /dev/null @@ -1,5 +0,0 @@ -const emailInput = "input[name=email]"; - -export const fillEmail = (email: string) => { - cy.get(emailInput).type(email); -} \ No newline at end of file diff --git a/airbyte-webapp-e2e-tests/cypress/pages/replicationPage.ts b/airbyte-webapp-e2e-tests/cypress/pages/replicationPage.ts index 708aa7dff14e4..5ccd986e005f5 100644 --- a/airbyte-webapp-e2e-tests/cypress/pages/replicationPage.ts +++ b/airbyte-webapp-e2e-tests/cypress/pages/replicationPage.ts @@ -1,5 +1,5 @@ const scheduleDropdown = "div[data-testid='schedule']"; -const scheduleValue = "div[data-testid='"; +const scheduleValue = (value: string) => `div[data-testid='${value}']`; const destinationPrefix = "input[data-testid='prefixInput']"; const replicationTab = "div[data-id='replication-step']"; const destinationNamespace = "div[data-testid='namespaceDefinition']"; @@ -21,7 +21,7 @@ export const enterConnectionName = (name: string) => { export const selectSchedule = (value: string) => { cy.get(scheduleDropdown).click(); - cy.get(scheduleValue + value + "']").click(); + cy.get(scheduleValue(value)).click(); } export const fillOutDestinationPrefix = (value: string) => { From cc8f8eab1cf05f209527e52fa59f0ede2d7544d9 Mon Sep 17 00:00:00 2001 From: Sofiia Zaitseva <108751383+SofiiaZaitseva@users.noreply.github.com> Date: Thu, 1 Sep 2022 21:39:29 +0300 Subject: [PATCH 07/11] fix goToDestinationPage signature --- airbyte-webapp-e2e-tests/cypress/pages/destinationPage.ts | 2 +- airbyte-webapp-e2e-tests/cypress/pages/replicationPage.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/airbyte-webapp-e2e-tests/cypress/pages/destinationPage.ts b/airbyte-webapp-e2e-tests/cypress/pages/destinationPage.ts index 62538a931baec..ebb253600dcdd 100644 --- a/airbyte-webapp-e2e-tests/cypress/pages/destinationPage.ts +++ b/airbyte-webapp-e2e-tests/cypress/pages/destinationPage.ts @@ -1,7 +1,7 @@ const newDestination = "button[data-id='new-destination'"; const addSourceButton = "div[data-testid='select-source']"; -export const openDestinationPage = () => { +export const goToDestinationPage = () => { cy.intercept("/api/v1/destinations/list").as("getDestinationsList"); cy.visit("/destination"); cy.wait(3000); diff --git a/airbyte-webapp-e2e-tests/cypress/pages/replicationPage.ts b/airbyte-webapp-e2e-tests/cypress/pages/replicationPage.ts index 5ccd986e005f5..093ef4c32d34d 100644 --- a/airbyte-webapp-e2e-tests/cypress/pages/replicationPage.ts +++ b/airbyte-webapp-e2e-tests/cypress/pages/replicationPage.ts @@ -1,4 +1,4 @@ -const scheduleDropdown = "div[data-testid='schedule']"; +const scheduleDropdown = "div[data-testid='scheduleData.basicSchedule']"; const scheduleValue = (value: string) => `div[data-testid='${value}']`; const destinationPrefix = "input[data-testid='prefixInput']"; const replicationTab = "div[data-id='replication-step']"; From 84182ef632d75f5f38135cb3366639b9c2dd9c2d Mon Sep 17 00:00:00 2001 From: Sofiia Zaitseva <108751383+SofiiaZaitseva@users.noreply.github.com> Date: Thu, 1 Sep 2022 22:44:55 +0300 Subject: [PATCH 08/11] move fillEmail method --- airbyte-webapp-e2e-tests/cypress/commands/common.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/airbyte-webapp-e2e-tests/cypress/commands/common.ts b/airbyte-webapp-e2e-tests/cypress/commands/common.ts index 902677bccd290..dc2b78c69afd2 100644 --- a/airbyte-webapp-e2e-tests/cypress/commands/common.ts +++ b/airbyte-webapp-e2e-tests/cypress/commands/common.ts @@ -21,3 +21,7 @@ export const clearApp = () => { cy.clearLocalStorage(); cy.clearCookies(); } + +export const fillEmail = (email: string) => { + cy.get("input[name=email]").type(email); +} From 3aa61a13ecf307367b0e766a9b8c473eeb4a1e3e Mon Sep 17 00:00:00 2001 From: Sofiia Zaitseva <108751383+SofiiaZaitseva@users.noreply.github.com> Date: Wed, 24 Aug 2022 15:35:09 +0300 Subject: [PATCH 09/11] change structure with using POM --- airbyte-webapp-e2e-tests/cypress/pages/onboaardingPage.ts | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 airbyte-webapp-e2e-tests/cypress/pages/onboaardingPage.ts diff --git a/airbyte-webapp-e2e-tests/cypress/pages/onboaardingPage.ts b/airbyte-webapp-e2e-tests/cypress/pages/onboaardingPage.ts new file mode 100644 index 0000000000000..9d462824355bd --- /dev/null +++ b/airbyte-webapp-e2e-tests/cypress/pages/onboaardingPage.ts @@ -0,0 +1,5 @@ +const emailInput = "input[name=email]"; + +export const fillEmail = (email: string) => { + cy.get(emailInput).type(email); +} \ No newline at end of file From 2428bf8c5d5e6c897ce75081bc0f6ddf1030c8d5 Mon Sep 17 00:00:00 2001 From: Sofiia Zaitseva <108751383+SofiiaZaitseva@users.noreply.github.com> Date: Thu, 1 Sep 2022 16:45:27 +0300 Subject: [PATCH 10/11] Fix coments --- airbyte-webapp-e2e-tests/cypress/pages/onboaardingPage.ts | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 airbyte-webapp-e2e-tests/cypress/pages/onboaardingPage.ts diff --git a/airbyte-webapp-e2e-tests/cypress/pages/onboaardingPage.ts b/airbyte-webapp-e2e-tests/cypress/pages/onboaardingPage.ts deleted file mode 100644 index 9d462824355bd..0000000000000 --- a/airbyte-webapp-e2e-tests/cypress/pages/onboaardingPage.ts +++ /dev/null @@ -1,5 +0,0 @@ -const emailInput = "input[name=email]"; - -export const fillEmail = (email: string) => { - cy.get(emailInput).type(email); -} \ No newline at end of file From 8778f89e20529f0b303dc3b60c7650c34ae670e0 Mon Sep 17 00:00:00 2001 From: Sofiia Zaitseva <108751383+SofiiaZaitseva@users.noreply.github.com> Date: Fri, 2 Sep 2022 18:42:47 +0300 Subject: [PATCH 11/11] Update connection.spec.ts fix request url and schedule dropdown value --- .../cypress/integration/connection.spec.ts | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/airbyte-webapp-e2e-tests/cypress/integration/connection.spec.ts b/airbyte-webapp-e2e-tests/cypress/integration/connection.spec.ts index 8a79c46f5e490..aefc883271948 100644 --- a/airbyte-webapp-e2e-tests/cypress/integration/connection.spec.ts +++ b/airbyte-webapp-e2e-tests/cypress/integration/connection.spec.ts @@ -23,7 +23,7 @@ describe("Connection main actions", () => { }); it("Update connection", () => { - cy.intercept("/api/v1/web_backend/connections/updateNew").as("updateConnection"); + cy.intercept("/api/v1/web_backend/connections/update").as("updateConnection"); createTestConnection("Test update connection source cypress", "Test update connection destination cypress"); @@ -37,6 +37,7 @@ describe("Connection main actions", () => { fillOutDestinationPrefix('auto_test'); submitButtonClick(); + cy.wait("@updateConnection").then((interception) => { assert.isNotNull(interception.response?.statusCode, '200'); }); @@ -48,9 +49,7 @@ describe("Connection main actions", () => { }); it("Update connection (pokeAPI)", () => { - cy.intercept({ - method: "POST", - url: "/api/v1/web_backend/connections/updateNew"}).as("updateConnection"); + cy.intercept("/api/v1/web_backend/connections/update").as("updateConnection"); createTestConnection("Test update connection PokeAPI source cypress", "Test update connection Local JSON destination cypress"); @@ -60,7 +59,7 @@ describe("Connection main actions", () => { goToReplicationTab(); - selectSchedule('Every 5 minutes'); + selectSchedule('Every hour'); fillOutDestinationPrefix('auto_test'); setupDestinationNamespaceCustomFormat('_test'); selectFullAppendSyncMode(); @@ -78,9 +77,9 @@ describe("Connection main actions", () => { namespaceFormat: '${SOURCE_NAMESPACE}_test', status: 'active', }); - expect(interception.request.body.schedule).to.contain({ - units: 5, - timeUnit: 'minutes' + expect(interception.request.body.scheduleData.basicSchedule).to.contain({ + units: 1, + timeUnit: 'hours' }); const streamToUpdate = interception.request.body.syncCatalog.streams[0];