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

make FE E2E tests more reliable #16759

Merged
merged 10 commits into from
Sep 17, 2022
3 changes: 2 additions & 1 deletion airbyte-webapp-e2e-tests/cypress.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@
"retries": {
"runMode": 2,
"openMode": 0
}
},
"defaultCommandTimeout": 10000
}
6 changes: 6 additions & 0 deletions airbyte-webapp-e2e-tests/cypress/commands/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,9 @@ export const clearApp = () => {
export const fillEmail = (email: string) => {
cy.get("input[name=email]").type(email);
};

// useful for ensuring that a name is unique from one test run to the next
export const appendRandomString = (string: string) => {
const randomString = Math.random().toString(36).substring(2,10);
return string + " _" + randomString;
}
4 changes: 4 additions & 0 deletions airbyte-webapp-e2e-tests/cypress/commands/workspaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,8 @@ export const initialSetupCompleted = (completed = true) => {
res.send(res.body);
});
});

cy.on('uncaught:exception', (err, runnable) => {
return false;
});
};
181 changes: 96 additions & 85 deletions airbyte-webapp-e2e-tests/cypress/integration/connection.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { deleteEntity, submitButtonClick } from "commands/common";
import { appendRandomString, deleteEntity, submitButtonClick } from "commands/common";
import { createTestConnection } from "commands/connection";
import { deleteDestination } from "commands/destination";
import { deleteSource } from "commands/source";
Expand All @@ -15,115 +15,126 @@ import {
import { openSourceDestinationFromGrid, goToSourcePage } from "pages/sourcePage";
import { goToSettingsPage } from "pages/settingsConnectionPage";

// describe("Connection main actions", () => {
// beforeEach(() => {
// initialSetupCompleted();
// });
describe("Connection main actions", () => {
beforeEach(() => {
initialSetupCompleted();
});

// it("Create new connection", () => {
// createTestConnection("Test connection source cypress", "Test connection destination cypress");
it("Create new connection", () => {
const sourceName = appendRandomString("Test connection source cypress");
const destName = appendRandomString("Test connection destination cypress")

// cy.get("div").contains("Test connection source cypress").should("exist");
// cy.get("div").contains("Test connection destination cypress").should("exist");
createTestConnection(sourceName, destName);

// deleteSource("Test connection source cypress");
// deleteDestination("Test connection destination cypress");
// });
cy.get("div").contains(sourceName).should("exist");
cy.get("div").contains(destName).should("exist");

// it("Update connection", () => {
// cy.intercept("/api/v1/web_backend/connections/update").as("updateConnection");
deleteSource(sourceName);
deleteDestination(destName);
});

// createTestConnection("Test update connection source cypress", "Test update connection destination cypress");
it("Update connection", () => {
cy.intercept("/api/v1/web_backend/connections/update").as("updateConnection");

// goToSourcePage();
// openSourceDestinationFromGrid("Test update connection source cypress");
// openSourceDestinationFromGrid("Test update connection destination cypress");
const sourceName = appendRandomString("Test update connection source cypress");
const destName = appendRandomString("Test update connection destination cypress");

// goToReplicationTab();
createTestConnection(sourceName, destName);

// selectSchedule("Every hour");
// fillOutDestinationPrefix("auto_test");
goToSourcePage();
openSourceDestinationFromGrid(sourceName);
openSourceDestinationFromGrid(destName);

// submitButtonClick();
goToReplicationTab();

// cy.wait("@updateConnection").then((interception) => {
// assert.isNotNull(interception.response?.statusCode, "200");
// });
selectSchedule("Every hour");
fillOutDestinationPrefix("auto_test");

// checkSuccessResult();
submitButtonClick();

// deleteSource("Test update connection source cypress");
// deleteDestination("Test update connection destination cypress");
// });
cy.wait("@updateConnection").then((interception) => {
assert.isNotNull(interception.response?.statusCode, "200");
});

// it("Update connection (pokeAPI)", () => {
// cy.intercept("/api/v1/web_backend/connections/update").as("updateConnection");
checkSuccessResult();

// createTestConnection(
// "Test update connection PokeAPI source cypress",
// "Test update connection Local JSON destination cypress"
// );
deleteSource(sourceName);
deleteDestination(destName);
});

// goToSourcePage();
// openSourceDestinationFromGrid("Test update connection PokeAPI source cypress");
// openSourceDestinationFromGrid("Test update connection Local JSON destination cypress");
it("Update connection (pokeAPI)", () => {
cy.intercept("/api/v1/web_backend/connections/update").as("updateConnection");

// goToReplicationTab();
const sourceName = appendRandomString("Test update connection PokeAPI source cypress");
const destName = appendRandomString("Test update connection Local JSON destination cypress")

// selectSchedule("Every hour");
// fillOutDestinationPrefix("auto_test");
// setupDestinationNamespaceCustomFormat("_test");
// selectFullAppendSyncMode();
createTestConnection(
sourceName,
destName
);

// submitButtonClick();
// confirmStreamConfigurationChangedPopup();
goToSourcePage();
openSourceDestinationFromGrid(sourceName);
openSourceDestinationFromGrid("Test update connection Local JSON destination cypress");

// 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",
// });
goToReplicationTab();

// const streamToUpdate = interception.request.body.syncCatalog.streams[0];
selectSchedule("Every hour");
fillOutDestinationPrefix("auto_test");
setupDestinationNamespaceCustomFormat("_test");
selectFullAppendSyncMode();

// expect(streamToUpdate.config).to.contain({
// aliasName: "pokemon",
// destinationSyncMode: "append",
// selected: true,
// });
submitButtonClick();
confirmStreamConfigurationChangedPopup();

// expect(streamToUpdate.stream).to.contain({
// name: "pokemon",
// });
// expect(streamToUpdate.stream.supportedSyncModes).to.contain("full_refresh");
// });
// checkSuccessResult();
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: sourceName + " <> " + destName + "Connection name",
prefix: "auto_test",
namespaceDefinition: "customformat",
namespaceFormat: "${SOURCE_NAMESPACE}_test",
status: "active",
});
expect(interception.request.body.scheduleData.basicSchedule).to.contain({
units: 1,
timeUnit: "hours",
});

// deleteSource("Test update connection PokeAPI source cypress");
// deleteDestination("Test update connection Local JSON destination cypress");
// });
const streamToUpdate = interception.request.body.syncCatalog.streams[0];

// it("Delete connection", () => {
// createTestConnection("Test delete connection source cypress", "Test delete connection destination cypress");
expect(streamToUpdate.config).to.contain({
aliasName: "pokemon",
destinationSyncMode: "append",
selected: true,
});

// goToSourcePage();
// openSourceDestinationFromGrid("Test delete connection source cypress");
// openSourceDestinationFromGrid("Test delete connection destination cypress");
expect(streamToUpdate.stream).to.contain({
name: "pokemon",
});
expect(streamToUpdate.stream.supportedSyncModes).to.contain("full_refresh");
});
checkSuccessResult();

// goToSettingsPage();
deleteSource(sourceName);
deleteDestination(destName);
});

// deleteEntity();
it("Delete connection", () => {
const sourceName = "Test delete connection source cypress";
const destName = "Test delete connection destination cypress";
createTestConnection(sourceName, destName);

// deleteSource("Test delete connection source cypress");
// deleteDestination("Test delete connection destination cypress");
// });
// });
goToSourcePage();
openSourceDestinationFromGrid(sourceName);
openSourceDestinationFromGrid(destName);

goToSettingsPage();

deleteEntity();

deleteSource(sourceName);
deleteDestination(destName);
});
});
13 changes: 8 additions & 5 deletions airbyte-webapp-e2e-tests/cypress/integration/destination.spec.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { appendRandomString } from "commands/common";
import { createLocalJsonDestination, deleteDestination, updateDestination } from "commands/destination";
import { initialSetupCompleted } from "commands/workspaces";

Expand All @@ -13,9 +14,10 @@ describe("Destination main actions", () => {
});

it("Update destination", () => {
createLocalJsonDestination("Test destination cypress for update", "/local");
const destName = appendRandomString("Test destination cypress for update");
createLocalJsonDestination(destName, "/local");
updateDestination(
"Test destination cypress for update",
destName,
"connectionConfiguration.destination_path",
"/local/my-json"
);
Expand All @@ -25,10 +27,11 @@ describe("Destination main actions", () => {
});

it("Delete destination", () => {
createLocalJsonDestination("Test destination cypress for delete", "/local");
deleteDestination("Test destination cypress for delete");
const destName = appendRandomString("Test destination cypress for delete");
createLocalJsonDestination(destName, "/local");
deleteDestination(destName);

cy.visit("/destination");
cy.get("div").contains("Test destination cypress for delete").should("not.exist");
cy.get("div").contains(destName).should("not.exist");
});
});
13 changes: 8 additions & 5 deletions airbyte-webapp-e2e-tests/cypress/integration/source.spec.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { appendRandomString } from "commands/common";
import { createPostgresSource, deleteSource, updateSource } from "commands/source";
import { initialSetupCompleted } from "commands/workspaces";

Expand All @@ -14,18 +15,20 @@ describe("Source main actions", () => {

//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");
updateSource("Test source cypress for update", "connectionConfiguration.start_date", "2020-11-11");
const sourceName = appendRandomString("Test source cypress for update");
createPostgresSource(sourceName);
updateSource(sourceName, "connectionConfiguration.start_date", "2020-11-11");

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

it("Delete source", () => {
createPostgresSource("Test source cypress for delete");
deleteSource("Test source cypress for delete");
const sourceName = appendRandomString("Test source cypress for delete");
createPostgresSource(sourceName);
deleteSource(sourceName);

cy.visit("/");
cy.get("div").contains("Test source cypress for delete").should("not.exist");
cy.get("div").contains(sourceName).should("not.exist");
});
});
5 changes: 3 additions & 2 deletions airbyte-webapp/src/components/base/Text/Text.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,17 @@ const isHeadingType = (props: TextProps | HeadingProps): props is HeadingProps =

export const Text: React.FC<React.PropsWithChildren<TextProps | HeadingProps>> = React.memo((props) => {
const isHeading = isHeadingType(props);
const { as = "p", centered = false, children } = props;
const { as = "p", centered = false, children, className: classNameProp, ...remainingProps } = props;

const className = classNames(
isHeading
? getHeadingClassNames({ centered, size: props.size ?? "md" })
: getTextClassNames({ centered, size: props.size ?? "md", bold: props.bold ?? false }),
props.className
classNameProp
);

return React.createElement(as, {
...remainingProps,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This was needed so that the data-id prop passed in here is actually set on the resulting element, so that our cypress tests still work

className,
children,
});
Expand Down