Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Jamakase/add cypress #2199

Merged
merged 13 commits into from
Mar 3, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/gradle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@ jobs:
if: success() && github.ref == 'refs/heads/master'
run: ./tools/bin/acceptance_test.sh

- name: Run End-to-End Frontend Tests
if: success() && github.ref == 'refs/heads/master'
run: ./tools/bin/e2e_test.sh

- name: Push Core Docker Images
if: success() && github.ref == 'refs/heads/master'
run: |
Expand Down
33 changes: 33 additions & 0 deletions airbyte-e2e-testing/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# production
/build

# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local

npm-debug.log*
yarn-debug.log*
yarn-error.log*

*.iml
/.idea

.npmrc
.env
.env.development
.env.production

/cypress/screenshots
/cypress/videos
/cypress/fixtures
5 changes: 5 additions & 0 deletions airbyte-e2e-testing/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
## Start Cypress

### `npm install`
### `npm run cypress:open`

20 changes: 20 additions & 0 deletions airbyte-e2e-testing/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
plugins {
id "base"
id "com.github.node-gradle.node" version "2.2.4"
}

node {
download = true
version = "14.11.0"
}


task e2etest(type: NpmTask) {
dependsOn npmInstall

args = ['run', 'cypress:ci']
inputs.files fileTree('cypress')
inputs.file 'package.json'
inputs.file 'package-lock.json'
}

9 changes: 9 additions & 0 deletions airbyte-e2e-testing/cypress.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"baseUrl": "http://localhost:3000",
"testFiles": [
"onboarding.spec.js",
"connection.spec.js",
"destination.spec.js",
"source.spec.js"
]
}
44 changes: 44 additions & 0 deletions airbyte-e2e-testing/cypress/integration/connection.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
describe("Connection main actions", () => {
it("Create new connection", () => {
cy.createTestConnection("Test connection source cypress", "Test destination cypress");

cy.get("div").contains("Test connection source cypress").should("exist");
cy.get("div").contains("Test destination cypress").should("exist");
});

it("Update connection", () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

each test depends on the state created by the previous test? am i reading that right? is there a reasonable way to not have this be the case. we generally try to make it so that the state of each test is totally isolated from one another.

cy.intercept("/api/v1/web_backend/connections/update").as("updateConnection");

cy.createTestConnection("Test update connection source cypress", "Test update connection destination cypress");

cy.visit("/");
cy.get("div").contains("Test update connection source cypress").click();
cy.get("div").contains("Test update connection destination cypress").click();

cy.get("div[data-id='settings-step']").click();

cy.get("div[role=combobox]").last().click();
cy.get("div[data-id='5m']").click();
cy.submit();
cy.wait("@updateConnection");
cy.get("span[data-id='success-result']").should("exist");

cy.get("div[data-id='status-step']").click();
cy.get("div").contains("5 min").should("exist");
});

it("Delete connection", () => {
cy.createTestConnection("Test delete connection source cypress", "Test delete connection destination cypress");

cy.visit("/");
cy.get("div").contains("Test delete connection source cypress").click();
cy.get("div").contains("Test delete connection destination cypress").click();

cy.get("div[data-id='settings-step']").click();

cy.deleteEntity();

cy.deleteSource("Test delete connection source cypress");
cy.deleteDestination("Test delete connection destination cypress");
});
});
23 changes: 23 additions & 0 deletions airbyte-e2e-testing/cypress/integration/destination.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
describe("Destination main actions", () => {
it("Create new destination", () => {
cy.createTestDestination("Test destination cypress");

cy.url().should("include", `${Cypress.config().baseUrl}/destination/`);
});

it("Update destination", () => {
cy.createTestDestination("Test destination cypress for update");
cy.updateDestination("Test destination cypress for update", "connectionConfiguration.destination_path", "/local/my-json");

cy.get("span[data-id='success-result']").should("exist");
cy.get("input[value='/local/my-json']").should("exist");
});

it("Delete destination", () => {
cy.createTestDestination("Test destination cypress for delete");
cy.deleteDestination("Test destination cypress for delete");

cy.visit("/destination");
cy.get("div").contains("Test destination cypress for delete").should("not.exist");
});
});
14 changes: 14 additions & 0 deletions airbyte-e2e-testing/cypress/integration/onboarding.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
describe("Onboarding actions", () => {
it("Skip onboardding", () => {
cy.visit("/");
cy.url().should("include", `${Cypress.config().baseUrl}/preferences`);

// cy.fillEmail("");
cy.submit();

cy.url().should("include", `${Cypress.config().baseUrl}/onboarding`);
cy.get("button[data-id='skip-onboarding']").click();

cy.url().should("equal", `${Cypress.config().baseUrl}/`);
});
});
23 changes: 23 additions & 0 deletions airbyte-e2e-testing/cypress/integration/source.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
describe("Source main actions", () => {
it("Create new source", () => {
cy.createTestSource("Test source cypress");

cy.url().should("include", `${Cypress.config().baseUrl}/source/`);
});

it("Update source", () => {
cy.createTestSource("Test source cypress for update");
cy.updateSource("Test source cypress for update", "connectionConfiguration.start_date", "2020-11-11");

cy.get("span[data-id='success-result']").should("exist");
cy.get("input[value='2020-11-11']").should("exist");
});

it("Delete source", () => {
cy.createTestSource("Test source cypress for delete");
cy.deleteSource("Test source cypress for delete");

cy.visit("/");
cy.get("div").contains("Test source cypress for delete").should("not.exist");
});
});
21 changes: 21 additions & 0 deletions airbyte-e2e-testing/cypress/plugins/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/// <reference types="cypress" />
// ***********************************************************
// This example plugins/index.js can be used to load plugins
//
// You can change the location of this file or turn off loading
// the plugins file with the 'pluginsFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/plugins-guide
// ***********************************************************

// This function is called when a project is opened or re-opened (e.g. due to
// the project's config changing)

/**
* @type {Cypress.PluginConfig}
*/
module.exports = (on, config) => {
// `on` is used to hook into various events Cypress emits
// `config` is the resolved Cypress config
}
70 changes: 70 additions & 0 deletions airbyte-e2e-testing/cypress/support/commands/common.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
Cypress.Commands.add("submit", () => {
cy.get("button[type=submit]").click();
})

Cypress.Commands.add("fillEmail", (email) => {
cy.get("input[name=email]").type(email);
})

Cypress.Commands.add("fillTestExchangeForm", (name) => {
cy.intercept("/source_definition_specifications/get").as("getSourceSpecifications");

cy.get("input[name=name]").type(name);
cy.get("div[role=combobox]").click();
cy.get("div").contains("Exchange Rates Api").click();

cy.wait("@getSourceSpecifications");

cy.get("input[name='connectionConfiguration.base']").type("USD");
cy.get("input[name='connectionConfiguration.start_date']").type("2020-12-12");
})

Cypress.Commands.add("fillTestLocalJsonForm", (name) => {
cy.intercept("/destination_definition_specifications/get").as("getDestinationSpecifications");

cy.get("input[name=name]").type(name);
cy.get("div[role=combobox]").click();
cy.get("div").contains("Local JSON").click();

cy.wait("@getDestinationSpecifications");

cy.get("input[name='connectionConfiguration.destination_path']").type("/local");
})

Cypress.Commands.add("openSourcePage", () => {
cy.visit("/");
cy.intercept("/sources/list").as("getSourcesList");
cy.wait("@getSourcesList");
})

Cypress.Commands.add("openDestinationPage", () => {
cy.visit("/destination");
cy.intercept("/destinations/list").as("getDestinationsList");
cy.wait("@getDestinationsList");
})

Cypress.Commands.add("openNewSourceForm", () => {
cy.openSourcePage();
cy.get("button[data-id='new-source'").click();
cy.url().should("eq", `${Cypress.config().baseUrl}/source/new-source`);
})

Cypress.Commands.add("openNewDestinationForm", () => {
cy.openDestinationPage();
cy.get("button[data-id='new-destination'").click();
cy.url().should("eq", `${Cypress.config().baseUrl}/destination/new-destination`);
})

Cypress.Commands.add("updateField", (field, value) => {
cy.get("input[name='" + field + "']").clear().type(value);
})

Cypress.Commands.add("openSettingForm", (name) => {
cy.get("div").contains(name).click();
cy.get("div[data-id='settings-step']").click();
})

Cypress.Commands.add("deleteEntity", () => {
cy.get("button[data-id='open-delete-modal']").click();
cy.get("button[data-id='delete']").click();
})
24 changes: 24 additions & 0 deletions airbyte-e2e-testing/cypress/support/commands/connection.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
Cypress.Commands.add("createTestConnection", (sourceName, destinationName) => {
cy.intercept("/api/v1/sources/check_connection").as("checkConnectionSource");
cy.intercept("/api/v1/destinations/check_connection").as("checkConnectionDestination");

cy.intercept("/api/v1/sources/discover_schema").as("discoverSchema");
cy.intercept("/api/v1/connections/create").as("createConnection");

cy.createTestSource(sourceName);
cy.createTestDestination(destinationName);
cy.wait(3000);

cy.get("div[role=combobox]").click();
cy.get("div").contains(sourceName).click();
cy.wait("@checkConnectionSource");
cy.wait("@checkConnectionDestination");

cy.wait("@discoverSchema");

cy.get("div[role=combobox]").last().click();
cy.get("div[data-id='manual']").click();
cy.submit();

cy.wait("@createConnection");
})
30 changes: 30 additions & 0 deletions airbyte-e2e-testing/cypress/support/commands/destination.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
Cypress.Commands.add("createTestDestination", (name) => {
cy.intercept("/scheduler/destinations/check_connection").as("checkDestinationConnection");
cy.intercept("/destinations/create").as("createDestination");

cy.openNewDestinationForm();
cy.fillTestLocalJsonForm(name);
cy.submit();

cy.wait("@checkDestinationConnection");
cy.wait("@createDestination");
})

Cypress.Commands.add("updateDestination", (name, field, value) => {
cy.intercept("/destinations/check_connection_for_update").as("checkDestinationUpdateConnection");
cy.intercept("/destinations/update").as("updateDestination");

cy.openDestinationPage();
cy.openSettingForm(name);
cy.updateField(field, value);
cy.submit();

cy.wait("@checkDestinationUpdateConnection");
cy.wait("@updateDestination");
})

Cypress.Commands.add("deleteDestination", (name) => {
cy.openDestinationPage();
cy.openSettingForm(name);
cy.deleteEntity();
})
4 changes: 4 additions & 0 deletions airbyte-e2e-testing/cypress/support/commands/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import "./common";
import "./source";
import "./destination";
import "./connection";
30 changes: 30 additions & 0 deletions airbyte-e2e-testing/cypress/support/commands/source.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
Cypress.Commands.add("createTestSource", (name) => {
cy.intercept("/scheduler/sources/check_connection").as("checkSourceUpdateConnection");
cy.intercept("/sources/create").as("createSource");

cy.openNewSourceForm();
cy.fillTestExchangeForm(name);
cy.submit();

cy.wait("@checkSourceUpdateConnection");
cy.wait("@createSource");
})

Cypress.Commands.add("updateSource", (name, field, value) => {
cy.intercept("/sources/check_connection_for_update").as("checkSourceConnection");
cy.intercept("/sources/update").as("updateSource");

cy.openSourcePage();
cy.openSettingForm(name);
cy.updateField(field, value);
cy.submit();

cy.wait("@checkSourceConnection");
cy.wait("@updateSource");
})

Cypress.Commands.add("deleteSource", (name) => {
cy.openSourcePage();
cy.openSettingForm(name);
cy.deleteEntity();
})
3 changes: 3 additions & 0 deletions airbyte-e2e-testing/cypress/support/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// Import commands.js using ES2015 syntax:
import './commands'

Loading