From 8ea3e4f7254c5129298be89a4805852483b59c08 Mon Sep 17 00:00:00 2001 From: Sofiia Zaitseva <108751383+SofiiaZaitseva@users.noreply.github.com> Date: Fri, 2 Sep 2022 19:40:46 +0300 Subject: [PATCH] 15700 add tests for PokeAPI (#15701) * add tests for PokeAPI * Update connection.spec.ts add body verification * add page object model for update connection (poke api) test * change structure with using POM * Select sync mode dropdown with a data-testid (#16053) * Fix coments * fix goToDestinationPage signature * move fillEmail method * change structure with using POM * Fix coments * Update connection.spec.ts fix request url and schedule dropdown value Co-authored-by: Alex Birdsall --- .../cypress/commands/common.ts | 44 +------- .../cypress/commands/connection.ts | 30 +++-- .../cypress/commands/connector.ts | 42 +++++++ .../cypress/commands/destination.ts | 16 ++- .../cypress/commands/sidebar.ts | 3 - .../cypress/commands/source.ts | 53 +++++---- .../cypress/integration/connection.spec.ts | 103 +++++++++++++++--- .../cypress/integration/destination.spec.ts | 8 +- .../cypress/integration/onboarding.spec.ts | 2 +- .../cypress/integration/source.spec.ts | 8 +- .../cypress/pages/createConnectorPage.ts | 48 ++++++++ .../cypress/pages/destinationPage.ts | 18 +++ .../cypress/pages/replicationPage.ts | 56 ++++++++++ .../cypress/pages/settingsConnectionPage.ts | 5 + .../cypress/pages/sidebar.ts | 5 + .../cypress/pages/sourcePage.ts | 17 +++ .../components/SyncSettingsDropdown.tsx | 1 + 17 files changed, 352 insertions(+), 107 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/replicationPage.ts create mode 100644 airbyte-webapp-e2e-tests/cypress/pages/settingsConnectionPage.ts create mode 100644 airbyte-webapp-e2e-tests/cypress/pages/sidebar.ts create mode 100644 airbyte-webapp-e2e-tests/cypress/pages/sourcePage.ts diff --git a/airbyte-webapp-e2e-tests/cypress/commands/common.ts b/airbyte-webapp-e2e-tests/cypress/commands/common.ts index 54ba9001a2c78..dc2b78c69afd2 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); } @@ -61,3 +21,7 @@ export const clearApp = () => { cy.clearLocalStorage(); cy.clearCookies(); } + +export const fillEmail = (email: string) => { + cy.get("input[name=email]").type(email); +} diff --git a/airbyte-webapp-e2e-tests/cypress/commands/connection.ts b/airbyte-webapp-e2e-tests/cypress/commands/connection.ts index e9a7ba8e31f79..55e8493a5c7b2 100644 --- a/airbyte-webapp-e2e-tests/cypress/commands/connection.ts +++ b/airbyte-webapp-e2e-tests/cypress/commands/connection.ts @@ -1,26 +1,36 @@ import { submitButtonClick } from "./common"; -import { createTestDestination } from "./destination"; -import { createTestSource } from "./source"; +import { createLocalJsonDestination } from "./destination"; +import { createPokeApiSource, 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"); cy.intercept("/api/v1/web_backend/connections/create").as("createConnection"); - createTestSource(sourceName); - createTestDestination(destinationName); + switch (true) { + case sourceName.includes('PokeAPI'): + createPokeApiSource(sourceName, "luxray") + break; + case sourceName.includes('Postgres'): + createPostgresSource(sourceName); + break; + default: + createPostgresSource(sourceName); + } + + 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..8abb5fbd12b0d --- /dev/null +++ b/airbyte-webapp-e2e-tests/cypress/commands/connector.ts @@ -0,0 +1,42 @@ +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( + "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); + enterPokemonName(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..2f3e54a7cfda9 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 { goToDestinationPage, 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"); + goToDestinationPage(); openNewDestinationForm(); - fillTestLocalJsonForm(name); + fillLocalJsonForm(name, destinationPath); submitButtonClick(); + cy.wait(3000); cy.wait("@checkDestinationConnection"); cy.wait("@createDestination"); } @@ -16,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(); @@ -26,7 +30,9 @@ export const updateDestination = (name: string, field: string, value: string) => } export const deleteDestination = (name: string) => { - openDestinationPage(); + cy.intercept("/api/v1/destinations/delete").as("deleteDestination"); + goToDestinationPage(); 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 d5f59e92de8de..479627e607dd6 100644 --- a/airbyte-webapp-e2e-tests/cypress/commands/source.ts +++ b/airbyte-webapp-e2e-tests/cypress/commands/source.ts @@ -1,33 +1,38 @@ -import { deleteEntity, openNewSourceForm, openSettingForm, openSourcePage, submitButtonClick, updateField } from "./common"; - -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" +import { deleteEntity, openSettingForm, submitButtonClick, updateField } from "./common"; +import { goToSourcePage, openNewSourceForm} from "pages/sourcePage"; +import { fillPostgresForm, fillPokeAPIForm } from "./connector" + +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" ); + cy.intercept("/api/v1/sources/create").as("createSource"); + + goToSourcePage(); + openNewSourceForm(); + fillPostgresForm(name, host, port, database, username, password); + submitButtonClick(); + + cy.wait("@checkSourceUpdateConnection"); + cy.wait("@createSource"); }; -export const createTestSource = (name: string) => { +export const createPokeApiSource = (name: string, pokeName: string) => { cy.intercept("/api/v1/scheduler/sources/check_connection").as( "checkSourceUpdateConnection" ); cy.intercept("/api/v1/sources/create").as("createSource"); + goToSourcePage(); openNewSourceForm(); - fillPgSourceForm(name); + fillPokeAPIForm(name, pokeName); submitButtonClick(); cy.wait("@checkSourceUpdateConnection"); @@ -40,7 +45,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(); @@ -50,7 +55,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 e8a05dfdd3481..aefc883271948 100644 --- a/airbyte-webapp-e2e-tests/cypress/integration/connection.spec.ts +++ b/airbyte-webapp-e2e-tests/cypress/integration/connection.spec.ts @@ -1,8 +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, 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(() => { @@ -10,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", () => { @@ -21,27 +27,90 @@ 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"); + + goToReplicationTab(); + + selectSchedule('Every hour'); + fillOutDestinationPrefix('auto_test'); + + submitButtonClick(); + + cy.wait("@updateConnection").then((interception) => { + assert.isNotNull(interception.response?.statusCode, '200'); + }); + + checkSuccessResult(); + + deleteSource("Test update connection source cypress"); + deleteDestination("Test update connection destination cypress"); + }); + + it("Update connection (pokeAPI)", () => { + cy.intercept("/api/v1/web_backend/connections/update").as("updateConnection"); - cy.get("div[data-id='replication-step']").click(); + createTestConnection("Test update connection PokeAPI source cypress", "Test update connection Local JSON destination cypress"); - cy.get("div[data-testid='scheduleData.basicSchedule']").click(); - cy.get("div[data-testid='Every hour']").click(); - cy.get("button[type=submit]").first().click(); - cy.wait("@updateConnection"); - cy.get("span[data-id='success-result']").should("exist"); -}); + goToSourcePage(); + openSourceDestinationFromGrid("Test update connection PokeAPI source cypress"); + openSourceDestinationFromGrid("Test update connection Local JSON destination cypress"); + + goToReplicationTab(); + + selectSchedule('Every hour'); + fillOutDestinationPrefix('auto_test'); + setupDestinationNamespaceCustomFormat('_test'); + selectFullAppendSyncMode(); + + submitButtonClick(); + 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.scheduleData.basicSchedule).to.contain({ + units: 1, + timeUnit: 'hours' + }); + + const streamToUpdate = interception.request.body.syncCatalog.streams[0]; + + expect(streamToUpdate.config).to.contain({ + aliasName: 'pokemon', + destinationSyncMode: 'append', + selected: true, + }); + + expect(streamToUpdate.stream).to.contain({ + name: "pokemon", + }); + expect(streamToUpdate.stream.supportedSyncModes).to.contain( + 'full_refresh' + ); + }) + 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..3e5d5446273f4 100644 --- a/airbyte-webapp-e2e-tests/cypress/integration/onboarding.spec.ts +++ b/airbyte-webapp-e2e-tests/cypress/integration/onboarding.spec.ts @@ -1,4 +1,4 @@ -import { fillEmail, submitButtonClick } from "commands/common"; +import { submitButtonClick, fillEmail } from "commands/common"; import { initialSetupCompleted } from "commands/workspaces"; describe("Preferences actions", () => { diff --git a/airbyte-webapp-e2e-tests/cypress/integration/source.spec.ts b/airbyte-webapp-e2e-tests/cypress/integration/source.spec.ts index 8f532ed109212..12bd0f38b206f 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"); 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"); 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"); 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..3915fe3478799 --- /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 pokemonNameInput = "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 enterPokemonName = (pokeName: string) => { + cy.get(pokemonNameInput).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..ebb253600dcdd --- /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 goToDestinationPage = () => { + 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/replicationPage.ts b/airbyte-webapp-e2e-tests/cypress/pages/replicationPage.ts new file mode 100644 index 0000000000000..093ef4c32d34d --- /dev/null +++ b/airbyte-webapp-e2e-tests/cypress/pages/replicationPage.ts @@ -0,0 +1,56 @@ +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']"; +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[data-testid='syncSettingsDropdown'] input"; +const successResult = "span[data-id='success-result']"; +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(); +} + +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 setupDestinationNamespaceSourceFormat = () => { + cy.get(destinationNamespace).click(); + cy.get(destinationNamespaceSource).click(); +} + +export const selectFullAppendSyncMode = () => { + 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"); +} + +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 new file mode 100644 index 0000000000000..dcd2719c6965a --- /dev/null +++ b/airbyte-webapp-e2e-tests/cypress/pages/sourcePage.ts @@ -0,0 +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`); + } 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 /> );