diff --git a/app/client/cypress/fixtures/datasources.json b/app/client/cypress/fixtures/datasources.json
index c7064b4d41..25e2bf48d6 100644
--- a/app/client/cypress/fixtures/datasources.json
+++ b/app/client/cypress/fixtures/datasources.json
@@ -34,10 +34,19 @@
"redshift-databaseName": "fakeapi",
"redshift-username": "root",
"redshift-password": "Redshift$123",
+
"smtp-host":"host.docker.internal",
"smtp-port":"25",
"smtp-username":"root",
"smtp-password":"root",
+
+ "OAuth_Username":"testuser@appsmith.com",
+ "OAuth_Host":"http://localhost:6001",
+ "OAuth_ApiUrl": "http://host.docker.internal:6001",
+ "OAUth_AccessTokenUrl": "http://host.docker.internal:6001/oauth/token",
+ "OAuth_AuthUrl": "http://localhost:6001/oauth/authorize",
+ "OAuth_RedirectUrl":"http://localhost/api/v1/datasources/authorize",
+
"restapi-url": "https://my-json-server.typicode.com/typicode/demo/posts",
"connection-type": "Replica set",
"database-url": "appsmith-f9fe4.firebaseio.com",
diff --git a/app/client/cypress/integration/Regression_TestSuite/ClientSideTests/Onboarding/CreateNewApp_spec.js b/app/client/cypress/integration/Regression_TestSuite/ClientSideTests/Onboarding/CreateNewApp_spec.js
index ec71c8ba19..8b6192c1a8 100644
--- a/app/client/cypress/integration/Regression_TestSuite/ClientSideTests/Onboarding/CreateNewApp_spec.js
+++ b/app/client/cypress/integration/Regression_TestSuite/ClientSideTests/Onboarding/CreateNewApp_spec.js
@@ -2,18 +2,17 @@ const explorerLocators = require("../../../../locators/explorerlocators.json");
const guidedTourLocators = require("../../../../locators/GuidedTour.json");
const commonlocators = require("../../../../locators/commonlocators.json");
const homePage = require("../../../../locators/HomePage");
-import { ObjectsRegistry } from "../../../../support/Objects/Registry";
-let datasources = ObjectsRegistry.DataSources;
+import * as _ from "../../../../support/Objects/ObjectsCore";
describe("Creating new app after discontinuing guided tour should not start the same", function() {
it("1. Creating new app after discontinuing guided tour should not start the same", function() {
// Start guided tour
- cy.get(commonlocators.homeIcon).click({ force: true });
- datasources.CloseReconnectDataSourceModal(); // Check if reconnect data source modal is visible and close it
+ _.homePage.NavigateToHome();
+ _.dataSources.CloseReconnectDataSourceModal(); // Check if reconnect data source modal is visible and close it
cy.get(guidedTourLocators.welcomeTour)
.click()
.wait(2000);
- datasources.CloseReconnectDataSourceModal(); // Check if reconnect data source modal is visible and close it
+ _.dataSources.CloseReconnectDataSourceModal(); // Check if reconnect data source modal is visible and close it
cy.get("body").then(($ele) => {
if ($ele.find(guidedTourLocators.welcomeTour).length) {
cy.get(guidedTourLocators.welcomeTour)
@@ -21,7 +20,7 @@ describe("Creating new app after discontinuing guided tour should not start the
.wait(2000);
}
});
- datasources.CloseReconnectDataSourceModal(); // Check if reconnect data source modal is visible and close it
+ _.dataSources.CloseReconnectDataSourceModal(); // Check if reconnect data source modal is visible and close it
cy.get("body").then(($ele) => {
if ($ele.find(guidedTourLocators.startBuilding).length == 0) {
diff --git a/app/client/cypress/integration/Regression_TestSuite/ServerSideTests/Datasources/AuthenticatedApiWithOAuth_spec.ts b/app/client/cypress/integration/Regression_TestSuite/ServerSideTests/Datasources/AuthenticatedApiWithOAuth_spec.ts
new file mode 100644
index 0000000000..e6ac5593b6
--- /dev/null
+++ b/app/client/cypress/integration/Regression_TestSuite/ServerSideTests/Datasources/AuthenticatedApiWithOAuth_spec.ts
@@ -0,0 +1,36 @@
+import * as _ from "../../../../support/Objects/ObjectsCore";
+//import * as _ from "@ObjectsCore"
+
+describe("Authentiacted Api with OAuth 2.O authorization code test cases", function() {
+ it("1. Create & Save an Authenticated API with OAuth 2.O authorization code", function() {
+ // Create OAuth client
+ cy.fixture("datasources").then((datasourceFormData: any) => {
+ _.dataSources.CreateOAuthClient("authorization_code");
+ // Create datasource
+ _.agHelper.GenerateUUID();
+ cy.get("@guid").then((uid) => {
+ cy.get("@OAuthClientID").then((clientId: any) => {
+ cy.get("@OAuthClientSecret").then((clientSecret: any) => {
+ _.dataSources.CreateOAuthDatasource(
+ "TED_OAuth_Api_" + uid,
+ "AuthCode",
+ clientId,
+ clientSecret,
+ );
+ //Create API from datasource
+ _.apiPage.CreateAndFillApi(
+ datasourceFormData["OAuth_ApiUrl"] + "/api/echo/get?ASDSA=ASDSA",
+ "EchoAPI_" + uid,
+ 10000,
+ "GET",
+ true,
+ );
+ });
+ });
+ });
+ });
+ //Run API & Validate Response
+ _.apiPage.RunAPI();
+ _.apiPage.ResponseStatusCheck("200");
+ });
+});
diff --git a/app/client/cypress/support/Pages/ApiPage.ts b/app/client/cypress/support/Pages/ApiPage.ts
index 845735099a..027a50152c 100644
--- a/app/client/cypress/support/Pages/ApiPage.ts
+++ b/app/client/cypress/support/Pages/ApiPage.ts
@@ -7,7 +7,7 @@ export class ApiPage {
public locator = ObjectsRegistry.CommonLocators;
private _createapi = ".t--createBlankApiCard";
- private _resourceUrl = ".t--dataSourceField";
+ _resourceUrl = ".t--dataSourceField";
private _headerKey = (index: number) =>
".t--actionConfiguration\\.headers\\[0\\]\\.key\\." + index + "";
private _headerValue = (index: number) =>
@@ -26,7 +26,7 @@ export class ApiPage {
".t--actionConfiguration\\.bodyFormData\\[0\\]\\.value\\." + index + "";
_bodyTypeDropdown =
"//span[text()='Type'][@class='bp3-button-text']/parent::button";
- private _apiRunBtn = ".t--apiFormRunBtn";
+ _apiRunBtn = ".t--apiFormRunBtn";
private _queryTimeout =
"//input[@name='actionConfiguration.timeoutInMillisecond']";
_responseBody = ".CodeMirror-code span.cm-string.cm-property";
@@ -57,13 +57,18 @@ export class ApiPage {
public _responseTabHeader = "[data-cy=t--tab-headers]";
public _autoGeneratedHeaderInfoIcon = (key: string) =>
`.t--auto-generated-${key}-info`;
+ private _createQuery = ".t--create-query";
CreateApi(
apiName = "",
apiVerb: "GET" | "POST" | "PUT" | "DELETE" | "PATCH" = "GET",
+ aftDSSaved = false,
) {
- cy.get(this.locator._createNew).click({ force: true });
- cy.get(this._blankAPI).click({ force: true });
+ if (aftDSSaved) this.agHelper.GetNClick(this._createQuery);
+ else {
+ cy.get(this.locator._createNew).click({ force: true });
+ cy.get(this._blankAPI).click({ force: true });
+ }
this.agHelper.ValidateNetworkStatus("@createNewApi", 201);
// cy.get("@createNewApi").then((response: any) => {
@@ -87,10 +92,10 @@ export class ApiPage {
apiName = "",
queryTimeout = 10000,
apiVerb: "GET" | "POST" | "PUT" | "DELETE" | "PATCH" = "GET",
+ aftDSSaved = false,
) {
- this.CreateApi(apiName, apiVerb);
+ this.CreateApi(apiName, apiVerb, aftDSSaved);
this.EnterURL(url);
- this.agHelper.AssertAutoSave();
//this.agHelper.Sleep(2000);// Added because api name edit takes some time to reflect in api sidebar after the call passes.
cy.get(this._apiRunBtn).should("not.be.disabled");
if (queryTimeout != 10000) this.SetAPITimeout(queryTimeout);
@@ -370,7 +375,7 @@ export class ApiPage {
ResponseStatusCheck(statusCode: string) {
this.agHelper.AssertElementVisible(this._responseStatus);
- this.agHelper.GetNAssertContains(this._responseStatus, statusCode)
+ this.agHelper.GetNAssertContains(this._responseStatus, statusCode);
}
public SelectPaginationTypeViaIndex(index: number) {
cy.get(this._paginationTypeLabels)
diff --git a/app/client/cypress/support/Pages/DataSources.ts b/app/client/cypress/support/Pages/DataSources.ts
index 148f20ba2e..5107ac35d9 100644
--- a/app/client/cypress/support/Pages/DataSources.ts
+++ b/app/client/cypress/support/Pages/DataSources.ts
@@ -123,17 +123,22 @@ export class DataSources {
public _urlInputControl = "input[name='url']";
// Authenticated API locators
+ private _authApiDatasource = ".t--createAuthApiDatasource";
private _authType = "[data-cy=authType]";
private _oauth2 = ".t--dropdown-option:contains('OAuth 2.0')";
private _accessTokenUrl = "[data-cy='authentication.accessTokenUrl'] input";
+ private _scope = "[data-cy='authentication.scopeString'] input";
private _clientID = "[data-cy='authentication.clientId'] input";
private _clientSecret = "[data-cy='authentication.clientSecret'] input";
+ private _clientCredentails =
+ ".t--dropdown-option:contains('Client Credentials')";
private _authorizationCode =
".t--dropdown-option:contains('Authorization Code')";
private _grantType = "[data-cy='authentication.grantType']";
private _authorizationURL =
"[data-cy='authentication.authorizationUrl'] input";
-
+ private _consent = '[name="confirm"]';
+ private _consentSubmit = "//button[text()='Submit']";
public _datasourceModalSave = ".t--datasource-modal-save";
public _datasourceModalDoNotSave = ".t--datasource-modal-do-not-save";
public _deleteDatasourceButton = ".t--delete-datasource";
@@ -481,7 +486,7 @@ export class DataSources {
}
public NavigateToActiveTab() {
- this.agHelper.GetElement(this.locator._body).then(($body) => {
+ this.agHelper.GetElement(this.locator._body).then(($body) => {
if ($body.find(this._selectedActiveTab).length == 0) {
this.NavigateToDSCreateNew();
this.agHelper.GetNClick(this._activeTab, 0, true);
@@ -900,4 +905,111 @@ export class DataSources {
uri,
);
}
+
+ public CreateOAuthClient(grantType: string) {
+ let clientId, clientSecret;
+
+ // Login to TED OAuth
+ let formData = new FormData();
+ formData.append("username", datasourceFormData["OAuth_Username"]);
+ cy.request("POST", datasourceFormData["OAuth_Host"], formData).then(
+ (response) => {
+ expect(response.status).to.equal(200);
+ },
+ );
+
+ // Create client
+ let clientData = new FormData();
+ clientData.append("client_name", "appsmith_cs_post");
+ clientData.append("client_uri", "http://localhost/");
+ clientData.append("scope", "profile");
+ clientData.append("redirect_uri", datasourceFormData["OAuth_RedirectUrl"]);
+ clientData.append("grant_type", grantType);
+ clientData.append("response_type", "code");
+ clientData.append("token_endpoint_auth_method", "client_secret_post");
+ cy.request(
+ "POST",
+ datasourceFormData["OAuth_Host"] + "/create_client",
+ clientData,
+ ).then((response) => {
+ expect(response.status).to.equal(200);
+ });
+
+ // Get Client Credentials
+ cy.request("GET", datasourceFormData["OAuth_Host"]).then((response) => {
+ clientId = response.body.split("client_id: ");
+ clientId = clientId[1].split("client_secret: ");
+ clientSecret = clientId[1].split("");
+ clientSecret = clientSecret[0].trim();
+ clientId = clientId[0].trim();
+ cy.wrap(clientId).as("OAuthClientID");
+ cy.wrap(clientSecret).as("OAuthClientSecret");
+ });
+ }
+
+ public CreateOAuthDatasource(
+ datasourceName: string,
+ grantType: "ClientCredentials" | "AuthCode",
+ clientId: string,
+ clientSecret: string,
+ ) {
+ this.NavigateToDSCreateNew();
+ //Click on Authenticated API
+ cy.get(this._authApiDatasource).click({ force: true });
+ this.FillAPIOAuthForm(datasourceName, grantType, clientId, clientSecret);
+
+ // save datasource
+ this.agHelper.Sleep(500);
+ this.agHelper.GetNClick(this._saveAndAuthorizeDS);
+
+ //Accept consent
+ this.agHelper.GetNClick(this._consent);
+ this.agHelper.GetNClick(this._consentSubmit);
+
+ //Validate save
+ this.agHelper.ValidateNetworkStatus("@saveDatasource", 201);
+ }
+
+ public FillAPIOAuthForm(
+ dsName: string,
+ grantType: "ClientCredentials" | "AuthCode",
+ clientId: string,
+ clientSecret: string,
+ ) {
+ this.agHelper.RenameWithInPane(dsName, false);
+ // Fill Auth Form
+ this.agHelper.UpdateInput(
+ this.locator._inputFieldByName("URL"),
+ datasourceFormData["OAuth_ApiUrl"],
+ );
+ this.agHelper.GetNClick(this._authType);
+ this.agHelper.GetNClick(this._oauth2);
+ this.agHelper.GetNClick(this._grantType);
+ if (grantType == "ClientCredentials")
+ this.agHelper.GetNClick(this._clientCredentails);
+ else if (grantType == "AuthCode")
+ this.agHelper.GetNClick(this._authorizationCode);
+
+ this.agHelper.UpdateInput(
+ this.locator._inputFieldByName("Access Token URL"),
+ datasourceFormData["OAUth_AccessTokenUrl"],
+ );
+
+ this.agHelper.UpdateInput(
+ this.locator._inputFieldByName("Client ID"),
+ clientId,
+ );
+ this.agHelper.UpdateInput(
+ this.locator._inputFieldByName("Client Secret"),
+ clientSecret,
+ );
+ this.agHelper.UpdateInput(
+ this.locator._inputFieldByName("Scope(s)"),
+ "profile",
+ );
+ this.agHelper.UpdateInput(
+ this.locator._inputFieldByName("Authorization URL"),
+ datasourceFormData["OAuth_AuthUrl"],
+ );
+ }
}