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

test: Add cypress tests for Hubspot Datasource functionalities #39419

Open
wants to merge 1 commit into
base: release
Choose a base branch
from

Conversation

laveena-en
Copy link
Contributor

@laveena-en laveena-en commented Feb 24, 2025

Description

Tip

Add a TL;DR when the description is longer than 500 words or extremely technical (helps the content, marketing, and DevRel team).

Please also include relevant motivation and context. List any dependencies that are required for this change. Add links to Notion, Figma or any other documents that might be relevant to the PR.

Fixes #Issue Number
or
Fixes Issue URL

Warning

If no issue exists, please create an issue first, and check with the maintainers if the issue is valid.

Automation

/ok-to-test tags=""

🔍 Cypress test results

Caution

If you modify the content in this section, you are likely to disrupt the CI result for your PR.

Communication

Should the DevRel and Marketing teams inform users about this change?

  • Yes
  • No

Summary by CodeRabbit

  • New Features

    • Enhanced HubSpot integration in the application with an improved configuration form supporting Bearer token authentication.
  • Tests

    • Added comprehensive end-to-end tests covering HubSpot datasource setup, query execution, widget data binding, deletion, and error handling scenarios.
  • Chores

    • Updated test specifications to include the new HubSpot tests and introduced a dedicated tag for easier test grouping.

Copy link
Contributor

coderabbitai bot commented Feb 24, 2025

Walkthrough

This pull request implements a suite of Cypress end-to-end tests for Hubspot datasource functionality. A new test file defines five cases verifying datasource configuration, query execution, widget binding, deletion, and error handling. The update also adds the new test path to the limited test specification file, integrates a Hubspot token into environment configurations within DataManager, and enhances the DataSources class with Hubspot-specific form handling (including a logo reference). Additionally, a new Hubspot tag is added to the tagging module.

Changes

Files Change Summary
app/.../Hubspot_spec.ts, app/.../limited-tests.txt Introduce end-to-end tests for the Hubspot datasource covering configuration, query execution, widget binding, deletion, and error handling; update limited-tests file with the new test spec entry.
app/.../DataManager.ts, app/.../DataSources.ts Add Hubspot support by incorporating a new hubspotBearerToken property in DataManager and introducing a FillHubspotDSForm method with an associated _imgHubspotLogo variable in DataSources for form handling.
app/.../tags.js Add new tag @tag.Hubspot to the existing tags array.

Sequence Diagram(s)

sequenceDiagram
    participant T as Test Runner
    participant DS as DataSources
    participant DM as DataManager
    participant HS as HubSpot API
    participant W as Widget

    %% Successful Flow
    T->>DS: Call FillHubspotDSForm(valid token)
    DS->>DM: Retrieve hubspotBearerToken
    DM-->>DS: Return token
    DS->>DS: Validate & fill form fields
    T->>HS: Execute query with valid config
    HS-->>T: Return query result
    T->>W: Bind result to widget
    W-->>T: Display expected data

    %% Error Handling Flow
    T->>DS: Call FillHubspotDSForm(invalid token)
    DS->>DM: Retrieve hubspotBearerToken
    DM-->>DS: Return token (invalid)
    T->>HS: Execute query with invalid config
    HS-->>T: Return error response
    T--)T: Verify error message display
Loading

Possibly related PRs

Suggested labels

skip-changelog, ok-to-test, Test, Integrations Product

Suggested reviewers

  • ApekshaBhosale
  • sagar-qa007
  • NandanAnantharamu

Poem

In the realm of tests and code so keen,
Hubspot's journey now unfolds on screen.
Tokens and forms in synchronized flight,
Errors and queries dance in the night.
Cheers to our code—a sparkling delight! 🚀

Happy testing!

✨ Finishing Touches
  • 📝 Generate Docstrings (Beta)

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@laveena-en
Copy link
Contributor Author

/ci-test-limit-count run_count=1 update_snapshot=false specs_to_run=cypress/e2e/Regression/ServerSide/Datasources/Hubspot_spec.ts

@github-actions github-actions bot added skip-changelog Adding this label to a PR prevents it from being listed in the changelog Test labels Feb 24, 2025
Copy link

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 6

🧹 Nitpick comments (3)
app/client/cypress/e2e/Regression/ServerSide/Datasources/Hubspot_spec.ts (3)

93-94: Remove commented code.

Remove commented code that's not being used. If it's needed for documentation, add it to the test description.

-// PageLeftPane.switchSegment(PagePaneSegment.UI); // Switching the tab to ensure connection reset from Hubspot platform gets refreshed
-// PageLeftPane.switchSegment(PagePaneSegment.Queries);

115-123: Remove commented code block.

Large blocks of commented code should be removed if they're not being used.

-// agHelper
-//   .GetElement(locators._widgetInDeployed(draggableWidgets.TEXT))
-//   .then(($elements) => {
-//     const values = $elements
-//       .map((_, el) => Cypress.$(el).text().trim())
-//       .get();
-//     expect(values).to.include("appsmith1");
-//   });

20-25: Consider splitting test suite by functionality.

The test suite has multiple tags including Git and AccessControl, but the tests only cover Hubspot datasource functionality.

-  tags: ["@tag.Datasource", "@tag.Git", "@tag.AccessControl", "@tag.Hubspot"],
+  tags: ["@tag.Datasource", "@tag.Hubspot"],
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 55a00b1 and d5e3efe.

📒 Files selected for processing (5)
  • app/client/cypress/e2e/Regression/ServerSide/Datasources/Hubspot_spec.ts (1 hunks)
  • app/client/cypress/limited-tests.txt (1 hunks)
  • app/client/cypress/support/Objects/DataManager.ts (2 hunks)
  • app/client/cypress/support/Pages/DataSources.ts (2 hunks)
  • app/client/cypress/tags.js (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
`app/client/cypress/**/**.*`: Review the following e2e test ...

app/client/cypress/**/**.*: Review the following e2e test code written using the Cypress test library. Ensure that:

  • Follow best practices for Cypress code and e2e automation.
  • Avoid using cy.wait in code.
  • Avoid using cy.pause in code.
  • Avoid using agHelper.sleep().
  • Use locator variables for locators and do not use plain strings.
  • Use data-* attributes for selectors.
  • Avoid Xpaths, Attributes and CSS path.
  • Avoid selectors like .btn.submit or button[type=submit].
  • Perform logins via API with LoginFromAPI.
  • Perform logout via API with LogOutviaAPI.
  • Perform signup via API with SignupFromAPI.
  • Avoid using it.only.
  • Avoid using after and aftereach in test cases.
  • Use multiple assertions for expect statements.
  • Avoid using strings for assertions.
  • Do not use duplicate filenames even with different paths.
  • Avoid using agHelper.Sleep, this.Sleep in any file in code.
  • app/client/cypress/limited-tests.txt
  • app/client/cypress/tags.js
  • app/client/cypress/support/Objects/DataManager.ts
  • app/client/cypress/e2e/Regression/ServerSide/Datasources/Hubspot_spec.ts
  • app/client/cypress/support/Pages/DataSources.ts
⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: client-unit-tests / client-unit-tests
  • GitHub Check: client-lint / client-lint
  • GitHub Check: client-build / client-build
  • GitHub Check: client-prettier / prettier-check
🔇 Additional comments (3)
app/client/cypress/tags.js (1)

29-29: LGTM! Tag addition follows conventions.

The new Hubspot tag is correctly placed in alphabetical order and follows the established naming pattern.

app/client/cypress/limited-tests.txt (1)

3-3: LGTM! Test spec path follows conventions.

The Hubspot test specification path follows the established pattern for regression tests.

app/client/cypress/support/Objects/DataManager.ts (1)

120-120: LGTM! Bearer token configuration follows patterns.

The Hubspot bearer token is correctly configured for both environments using environment variables, consistent with other datasource configurations.

Also applies to: 222-222

@@ -317,6 +317,7 @@ export class DataSources {
private _entityTriggerElement = ".t--template-menu-trigger";
_dsSchemaTableResponse = ".t--table-response";
_imgSnowflakeLogo = "//img[contains(@src, 'snowflake.svg')]";
_imgHubspotLogo = "//img[contains(@src, 'hubspot.png')]";
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Replace XPath with data- attribute selector.*

Using XPath selectors is against the coding guidelines. Use data-* attributes for more reliable and maintainable selectors.

-  _imgHubspotLogo = "//img[contains(@src, 'hubspot.png')]";
+  _imgHubspotLogo = "[data-testid='hubspot-logo-img']";
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
_imgHubspotLogo = "//img[contains(@src, 'hubspot.png')]";
_imgHubspotLogo = "[data-testid='hubspot-logo-img']";

Comment on lines +612 to +630
public FillHubspotDSForm(
environment = this.dataManager.defaultEnviorment,
password = "",
) {
this.ValidateNSelectDropdown(
"Authentication type",
"Please select an option",
"Bearer token",
);
this.agHelper.TypeText(
this.locator._inputFieldByName("Bearer token") +
"//" +
this.locator._inputField,
!password
? this.dataManager.dsValues[environment].hubspotBearerToken
: password,
);
this.agHelper.Sleep();
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Remove agHelper.Sleep() and use proper wait conditions.

Using Sleep() is against the coding guidelines. Use proper wait conditions or assertions instead.

  public FillHubspotDSForm(
    environment = this.dataManager.defaultEnviorment,
    password = "",
  ) {
    this.ValidateNSelectDropdown(
      "Authentication type",
      "Please select an option",
      "Bearer token",
    );
    this.agHelper.TypeText(
      this.locator._inputFieldByName("Bearer token") +
        "//" +
        this.locator._inputField,
      !password
        ? this.dataManager.dsValues[environment].hubspotBearerToken
        : password,
    );
-   this.agHelper.Sleep();
+   this.agHelper.WaitUntilAllToastsDisappear();
  }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
public FillHubspotDSForm(
environment = this.dataManager.defaultEnviorment,
password = "",
) {
this.ValidateNSelectDropdown(
"Authentication type",
"Please select an option",
"Bearer token",
);
this.agHelper.TypeText(
this.locator._inputFieldByName("Bearer token") +
"//" +
this.locator._inputField,
!password
? this.dataManager.dsValues[environment].hubspotBearerToken
: password,
);
this.agHelper.Sleep();
}
public FillHubspotDSForm(
environment = this.dataManager.defaultEnviorment,
password = "",
) {
this.ValidateNSelectDropdown(
"Authentication type",
"Please select an option",
"Bearer token",
);
this.agHelper.TypeText(
this.locator._inputFieldByName("Bearer token") +
"//" +
this.locator._inputField,
!password
? this.dataManager.dsValues[environment].hubspotBearerToken
: password,
);
this.agHelper.WaitUntilAllToastsDisappear();
}

Comment on lines +69 to +71
cy.wait(assertHelper.GetAliasName("@postExecute"), {
timeout: responseTimeout,
})
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Remove cy.wait and agHelper.Sleep calls.

According to the coding guidelines:

  • Avoid using cy.wait in code
  • Avoid using agHelper.sleep()

Replace the wait and sleep calls with proper Cypress commands that wait for specific conditions:

-cy.wait(assertHelper.GetAliasName("@postExecute"), {
-  timeout: responseTimeout,
-});
+cy.intercept('POST', '**/postExecute').as('postExecute');
+cy.get(assertHelper.GetAliasName("@postExecute")).should('exist');

-assertHelper.Sleep();
+cy.get(assertHelper.GetAliasName("@postExecute")).should('not.exist');

Also applies to: 84-84

it("1. Validate the configuration of Hubspot datasource", () => {
dataSources.NavigateToDSCreateNew();
dataSources.CreatePlugIn("HubSpot");
agHelper.AssertElementVisibility(dataSources._imgHubspotLogo, true, 0); // Ensure the Hubspot logo is visible
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Use data- attributes for selectors.*

According to the guidelines, we should:

  • Use data-* attributes for selectors
  • Avoid using plain strings in assertions

Replace the current selectors with data-* attributes:

-agHelper.AssertElementVisibility(dataSources._imgHubspotLogo, true, 0);
+agHelper.AssertElementVisibility('[data-testid="hubspot-logo"]', true, 0);

-cy.get(locators._widgetInDeployed(draggableWidgets.TEXT)).should(
-  "contain.text",
-  "appsmith1",
-);
+cy.get('[data-testid="text-widget"]').should(($el) => {
+  expect($el.text().trim()).to.equal("appsmith1");
+});

-cy.get(locators._widgetInDeployed(draggableWidgets.TEXT)).should(
-  "have.text",
-  "",
-);
+cy.get('[data-testid="text-widget"]').should(($el) => {
+  expect($el.text().trim()).to.equal("");
+});

Also applies to: 111-114, 138-141

dataSources.FillHubspotDSForm(undefined, "wrongpassword");
dataSources.SaveDatasource(false);
dataSources.CreateQueryForDS("Untitled datasource 1");
agHelper.RefreshPage(); // Refreshing the page due to frequent connection reset from Hubspot
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Remove page refresh call.

The code uses agHelper.RefreshPage() which should be avoided. Instead, handle the connection reset gracefully using proper test setup and teardown.

-agHelper.RefreshPage(); // Refreshing the page due to frequent connection reset from Hubspot
+// Handle connection reset by implementing proper retry mechanism or connection handling
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
agHelper.RefreshPage(); // Refreshing the page due to frequent connection reset from Hubspot
// Handle connection reset by implementing proper retry mechanism or connection handling

Comment on lines +61 to +92
const fireApi = (retries = 5, responseTimeout = 100000) => {
if (retries === 0) {
throw new Error("Max retries reached, API did not return success.");
}

dataSources.RunQuery({
toValidateResponse: false,
});
cy.wait(assertHelper.GetAliasName("@postExecute"), {
timeout: responseTimeout,
})
.then((interceptions) => {
return cy
.get(assertHelper.GetAliasName("@postExecute"), {
timeout: responseTimeout,
})
.its("response");
})
.then((response) => {
const { isExecutionSuccess } = response.body.data;

if (!isExecutionSuccess) {
cy.log(`Retrying... Attempts left: ${retries - 1}`);
assertHelper.Sleep();
fireApi(retries - 1);
} else {
expect(isExecutionSuccess).to.eq(true);
}
});
};

fireApi(5);
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Refactor retry mechanism to use Cypress built-in retries.

The custom retry mechanism can be replaced with Cypress's built-in retry-ability and assertions.

-const fireApi = (retries = 5, responseTimeout = 100000) => {
-  if (retries === 0) {
-    throw new Error("Max retries reached, API did not return success.");
-  }
-
-  dataSources.RunQuery({
-    toValidateResponse: false,
-  });
-  cy.wait(assertHelper.GetAliasName("@postExecute"))
-    .then((interceptions) => {
-      return cy.get(assertHelper.GetAliasName("@postExecute"))
-        .its("response");
-    })
-    .then((response) => {
-      const { isExecutionSuccess } = response.body.data;
-
-      if (!isExecutionSuccess) {
-        cy.log(`Retrying... Attempts left: ${retries - 1}`);
-        assertHelper.Sleep();
-        fireApi(retries - 1);
-      } else {
-        expect(isExecutionSuccess).to.eq(true);
-      }
-    });
-};
-
-fireApi(5);
+dataSources.RunQuery({
+  toValidateResponse: false,
+});
+
+cy.intercept('POST', '**/postExecute').as('postExecute');
+cy.get('@postExecute').should('exist').then((interception) => {
+  expect(interception.response.body.data.isExecutionSuccess).to.eq(true);
+});

Committable suggestion skipped: line range outside the PR's diff.

Copy link

Workflow run: https://github.com/appsmithorg/appsmith/actions/runs/13497602031.
Cypress dashboard url: Click here!
All Cypress tests have passed 🎉🎉🎉

***** Repeat Run Summary ***** Total Tests with repeat: 5 Total Passed: 5 Total Failed: 0 Total Skipped: 0 *****************************

@laveena-en
Copy link
Contributor Author

/ci-test-limit-count run_count=10 update_snapshot=false runId=13497602031 specs_to_run=cypress/e2e/Regression/ServerSide/Datasources/Hubspot_spec.ts

Copy link

Copy link

Workflow run: https://github.com/appsmithorg/appsmith/actions/runs/13498198564.
Cypress dashboard url: Click here!
All cypress tests have passed 🎉🎉🎉

***** Repeat Run Summary ***** Total Tests with repeat: 50 Total Passed: 50 Total Failed: 0 Total Skipped: 0 *****************************

@laveena-en
Copy link
Contributor Author

/ci-test-limit-count run_count=40 update_snapshot=false runId=13497602031 specs_to_run=cypress/e2e/Regression/ServerSide/Datasources/Hubspot_spec.ts

Copy link

Copy link

Workflow run: https://github.com/appsmithorg/appsmith/actions/runs/13499747208.
Cypress dashboard: Click here!
The following are new failures, please fix them before merging the PR:
To know the list of identified flaky tests - Refer here

***** Repeat Run Summary ***** Total Tests with repeat: 200 Total Passed: 197 Total Failed: 3 Total Skipped: 0 *****************************

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
skip-changelog Adding this label to a PR prevents it from being listed in the changelog Test
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant