PromucFlow_constructor/app/client/cypress/support/Pages/DataSources.ts
sneha122 f36bcf2a6c
feat: query creation dumb templates replaced with smart templates (#24234)
## Description
 
This PR replaces dumb template that is shown on new query creation with
smart templates. With current implementation whenever we create a new DB
query, we see this template before writing the query, when we select any
of the template options, it shows us template query like `SELECT * FROM
users ORDER BY id LIMIT 10;` Since its a template query, users table may
not exist in user's actual database, thus leading them to error results.
<img width="1174" alt="Screenshot 2023-06-09 at 2 45 40 PM"
src="https://github.com/appsmithorg/appsmith/assets/30018882/4dede184-439f-4064-abe0-faf7b236748e">

With new implementation, we are removing this template page, instead if
we have the structure of the datasource available, we would simply get
the first table from the structure, and create select query using that.
This way we are populating query editor with user's actual table names
rather than dumb table name like `users`. Thus leading users to create
successful query

Note: This change is done only for sql plugins like MySQL, MSSQL,
PostgreSQL, Redshift, Oracle, Snowflake.

#### PR fixes following issue(s)
Fixes #23960 
> if no issue exists, please create an issue and ask the maintainers
about this first
>
>
#### Media
> A video or a GIF is preferred. when using Loom, don’t embed because it
looks like it’s a GIF. instead, just link to the video
>
>
#### Type of change
- New feature (non-breaking change which adds functionality)
>
>
>
## Testing
>
#### How Has This Been Tested?
> Please describe the tests that you ran to verify your changes. Also
list any relevant details for your test configuration.
> Delete anything that is not relevant
- [x] Manual
- [ ] Jest
- [x] Cypress
>
>
#### Test Plan
> Create a Connection on the DB 
> Create a Query from the established Query
> Ensure the 1st table data is placed when Add Query button is clicked
from the Review page
> If the query is created from Entity explorer ensure the right table
name is been added

#### Issues raised during DP testing
> Link issues raised during DP testing for better visibility and
tracking (copy link from comments dropped on this PR)
>
>
>
## Checklist:
#### Dev activity
- [x] My code follows the style guidelines of this project
- [x] I have performed a self-review of my own code
- [x] I have commented my code, particularly in hard-to-understand areas
- [ ] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my
feature works
- [ ] New and existing unit tests pass locally with my changes
- [ ] PR is being merged under a feature flag


#### QA activity:
- [ ] [Speedbreak
features](https://github.com/appsmithorg/TestSmith/wiki/Test-plan-implementation#speedbreaker-features-to-consider-for-every-change)
have been covered
- [x] Test plan covers all impacted features and [areas of
interest](https://github.com/appsmithorg/TestSmith/wiki/Guidelines-for-test-plans/_edit#areas-of-interest)
- [ ] Test plan has been peer reviewed by project stakeholders and other
QA members
- [x] Manually tested functionality on DP
- [ ] We had an implementation alignment call with stakeholders post QA
Round 2
- [x] Cypress test cases have been added and approved by SDET/manual QA
- [x] Added `Test Plan Approved` label after Cypress tests were reviewed
- [ ] Added `Test Plan Approved` label after JUnit tests were reviewed

---------

Co-authored-by: “sneha122” <“sneha@appsmith.com”>
Co-authored-by: Aishwarya UR <aishwarya@appsmith.com>
2023-06-19 15:23:34 +05:30

1343 lines
46 KiB
TypeScript

import { ObjectsRegistry } from "../Objects/Registry";
import { WIDGET } from "../../locators/WidgetLocators";
import { EntityItems } from "./AssertHelper";
const DataSourceKVP = {
Postgres: "PostgreSQL",
Mongo: "MongoDB",
MySql: "MySQL",
UnAuthenticatedGraphQL: "GraphQL API",
MsSql: "Microsoft SQL Server",
Airtable: "Airtable",
Arango: "ArangoDB",
Firestore: "Firestore",
Elasticsearch: "Elasticsearch",
Redis: "Redis",
Oracle: "Oracle",
}; //DataSources KeyValuePair
export enum Widgets {
Dropdown,
Table,
Chart,
Text,
}
interface RunQueryParams {
toValidateResponse?: boolean;
expectedStatus?: boolean;
waitTimeInterval?: number;
}
export class DataSources {
private agHelper = ObjectsRegistry.AggregateHelper;
private table = ObjectsRegistry.Table;
private ee = ObjectsRegistry.EntityExplorer;
private locator = ObjectsRegistry.CommonLocators;
private apiPage = ObjectsRegistry.ApiPage;
private hp = ObjectsRegistry.DefaultHostPort;
private assertHelper = ObjectsRegistry.AssertHelper;
private _dsCreateNewTab = "[data-testid=t--tab-CREATE_NEW]";
private _addNewDataSource = ".t--entity-add-btn.datasources button";
private _createNewPlgin = (pluginName: string) =>
".t--plugin-name:contains('" + pluginName + "')";
private _collapseContainer = ".t--collapse-section-container";
private _collapseSettings =
"[data-testid='t--dropdown-connection.ssl.authType']";
public _host = "input[name='datasourceConfiguration.endpoints[0].host']";
public _port = "input[name='datasourceConfiguration.endpoints[0].port']";
_databaseName =
"input[name='datasourceConfiguration.authentication.databaseName']";
private _username =
"input[name='datasourceConfiguration.authentication.username']";
private _section = (name: string) =>
"//div[text()='" + name + "']/parent::div";
private _sectionState = (name: string) =>
this._section(name) +
"/following-sibling::div/div[@class ='bp3-collapse-body']";
private _password =
"input[name = 'datasourceConfiguration.authentication.password']";
private _testDs = ".t--test-datasource";
_saveAndAuthorizeDS = ".t--save-and-authorize-datasource";
_saveDs = ".t--save-datasource";
_datasourceCard = ".t--datasource";
_dsMenuoptions = "div.t--datasource-menu-option";
_editButton = ".t--edit-datasource";
_reconnectDataSourceModal = "[data-testid=t--tab-RECONNECT_DATASOURCES]";
_closeDataSourceModal = ".t--reconnect-close-btn";
_dsEntityItem = "[data-guided-tour-id='explorer-entity-Datasources']";
_activeDS = "[data-testid='active-datasource-name']";
_mockDatasourceName = "[data-testid=mockdatasource-name]";
_templateMenu = ".t--template-menu";
_templateMenuOption = (action: string) =>
"//div[contains(@class, 't--template-menu')]//div[text()='" + action + "']";
_createQuery = ".t--create-query";
_visibleTextSpan = (spanText: string) =>
"//span[contains(text(),'" + spanText + "')]";
_dsOptionMenuItem = (text: string) =>
"//div[@role='menuitem']//span[text()='" + text + "']";
_dropdownTitle = (ddTitle: string) =>
"//p[contains(text(),'" +
ddTitle +
"')]/ancestor::div[@class='form-config-top']/following-sibling::div[@class='t--form-control-DROP_DOWN']//input | //label[text()='" +
ddTitle +
"']/following-sibling::span//button";
_reconnectModal = "[data-testid='reconnect-datasource-modal']";
_dropdown = (ddTitle: string) =>
"//span[contains(@title, '" +
ddTitle +
"') and text() = '" +
ddTitle +
"']";
_activeDSListReconnectModal = (dbName: string) =>
"//div[contains(@class, 't--ds-list')]//span[text()='" + dbName + "']";
_runQueryBtn = ".t--run-query";
_newDatabases = "#new-datasources";
_newDatasourceContainer = "#new-integrations-wrapper";
_selectDatasourceDropdown = "[data-testid=t--datasource-dropdown]";
_selectTableDropdown =
"[data-testid=t--table-dropdown] .rc-select-selection-item";
_selectSheetNameDropdown = "[data-testid=t--sheetName-dropdown]";
_selectTableHeaderIndexInput = "[data-testid=t--tableHeaderIndex]";
_dropdownOption = ".rc-select-item-option-content";
_generatePageBtn = "[data-testid=t--generate-page-form-submit]";
_selectedRow = ".tr.selected-row";
_activeTab = "span:contains('Active')";
_selectedActiveTab = "li[aria-selected='true'] " + this._activeTab;
_contextMenuDSReviewPage = "[data-testid='t--context-menu-trigger']";
_contextMenuDelete = ".t--datasource-option-delete";
_datasourceCardGeneratePageBtn = ".t--generate-template";
_queryOption = (option: string) =>
"//div[contains(@class, 'rc-select-item-option-content') and text() = '" +
option +
"'] | //a[contains(@class, 'single-select')]//div[text()='" +
option +
"']";
_queryTableResponse =
"//div[@data-guided-tour-id='query-table-response']//div[@class='tbody']//div[@class ='td']";
_queryResponseHeader = (header: string) =>
"//div[@data-guided-tour-id='query-table-response']//div[@class='table']//div[@role ='columnheader']//span[text()='" +
header +
"']";
_refreshIcon = "button .bp3-icon-refresh";
_addIcon = "button .bp3-icon-add";
_queryError = "[data-testid='t--query-error']";
_queryEditorTabs = (responseType: string) =>
"//button[@role='tab' or @role='tablist']//span[text()='" +
responseType +
"']";
_queryResponse = (responseType: string) =>
"//div[@data-testid='t--response-tab-segmented-control']//span[text()='" +
responseType +
"']";
_queryRecordResult = (recordCount: number) =>
`//div/span[text()='Result:']/span[contains(text(),' ${recordCount} Record')]`;
_noRecordFound = "span[data-testid='no-data-table-message']";
_usePreparedStatement =
"input[name='actionConfiguration.pluginSpecifiedTemplates[0].value'][type='checkbox']";
_queriesOnPageText = (dsName: string) =>
".t--datasource-name:contains('" + dsName + "') .t--queries-for-DB";
_mockDB = (dbName: string) =>
"//span[text()='" +
dbName +
"']/ancestor::div[contains(@class, 't--mock-datasource')][1]";
private _createBlankGraphQL = ".t--createBlankApiGraphqlCard";
private _createBlankCurl = ".t--createBlankCurlCard";
private _graphQLHeaderKey = "input[name='headers[0].key']";
private _graphQLHeaderValue = "input[name='headers[0].value']";
_graphqlQueryEditor = ".t--graphql-query-editor";
_graphqlVariableEditor = ".t--graphql-variable-editor";
_graphqlPagination = {
_limitVariable: ".t--apiFormPaginationLimitVariable .rc-select-selector",
_limitValue: ".t--apiFormPaginationLimitValue .CodeMirror textarea",
_offsetVariable: ".t--apiFormPaginationOffsetVariable .rc-select-selector",
_offsetValue: ".t--apiFormPaginationOffsetValue .CodeMirror textarea",
_prevLimitVariable: ".t--apiFormPaginationPrevLimitVariable",
_prevLimitValue: ".t--apiFormPaginationPrevLimitValue .CodeMirror textarea",
_prevCursorVariable: ".t--apiFormPaginationPrevCursorVariable",
_prevCursorValue:
".t--apiFormPaginationPrevCursorValue .CodeMirror textarea",
_nextLimitVariable: ".t--apiFormPaginationNextLimitVariable",
_nextLimitValue: ".t--apiFormPaginationNextLimitValue .CodeMirror textarea",
_nextCursorVariable: ".t--apiFormPaginationNextCursorVariable",
_nextCursorValue:
".t--apiFormPaginationNextCursorValue .CodeMirror textarea",
};
_queryDoc = ".t--datasource-documentation-link";
_globalSearchModal = ".t--global-search-modal";
_globalSearchInput = (inputText: string) =>
"//input[@id='global-search'][@value='" + inputText + "']";
_gsScopeDropdown =
"[data-testid='datasourceConfiguration.authentication.scopeString']";
_gsScopeOptions = ".ads-v2-select__dropdown .rc-select-item-option";
private _queryTimeout =
"//input[@name='actionConfiguration.timeoutInMillisecond']";
_getStructureReq = "/api/v1/datasources/*/structure?ignoreCache=true";
_editDatasourceFromActiveTab = (dsName: string) =>
".t--datasource-name:contains('" + dsName + "')";
private _suggestedWidget = (widgetType: string) =>
".t--suggested-widget-" + widgetType + "";
private _curlTextArea =
"//label[text()='Paste CURL Code Here']/parent::form/div";
_noSchemaAvailable = (dbName: string) =>
"//div[text()='" +
dbName +
"']/ancestor::div[contains(@class, 't--entity-item')]/following-sibling::div//p[text()='Schema not available']";
// Authenticated API locators
private _authApiDatasource = ".t--createAuthApiDatasource";
private _authType = "[data-testid=authType]";
private _oauth2 = ".rc-select-item-option:contains('OAuth 2.0')";
private _accessTokenUrl =
"[data-testid='authentication.accessTokenUrl'] input";
private _scope = "[data-testid='authentication.scopeString'] input";
private _clientID = "[data-testid='authentication.clientId'] input";
private _clientSecret = "[data-testid='authentication.clientSecret'] input";
private _clientCredentails =
".rc-select-item-option:contains('Client Credentials')";
private _authorizationCode =
".rc-select-item-option:contains('Authorization Code')";
private _grantType = "[data-testid='authentication.grantType']";
private _authorizationURL =
"[data-testid='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 _cancelEditDatasourceButton = ".t--cancel-edit-datasource";
public _urlInputControl = "input[name='url']";
public _mongoCollectionPath = "t--actionConfiguration.formData.collection";
private _getJSONswitchLocator = (fieldLocator: string) =>
`[data-testid='${fieldLocator}.data-JS']`;
_nestedWhereClauseKey = (index: number) =>
".t--actionConfiguration\\.formData\\.where\\.data\\.children\\[" +
index +
"\\]\\.key";
_nestedWhereClauseValue = (index: number) =>
".t--actionConfiguration\\.formData\\.where\\.data\\.children\\[" +
index +
"\\]\\.value";
_whereDelete = (index: number) =>
"[data-testid='t--where-clause-delete-[" + index + "]']";
_bodyCodeMirror = "//div[contains(@class, 't--actionConfiguration.body')]";
public AssertDSEditViewMode(mode: "Edit" | "View") {
if (mode == "Edit") this.agHelper.AssertElementAbsence(this._editButton);
else if (mode == "View") this.agHelper.AssertElementExist(this._editButton);
}
public GeneratePageWithDB(datasourceName: any, tableName: string) {
this.ee.AddNewPage("Generate page with data");
this.agHelper.GetNClick(this._selectDatasourceDropdown);
this.agHelper.GetNClickByContains(
this.locator._dropdownText,
datasourceName,
);
this.agHelper.GetNClick(this._selectTableDropdown, 0, true);
cy.get(
`div[role="listbox"] p[kind="span"]:contains("${tableName}")`,
).click();
this.agHelper.GetNClick(this._generatePageBtn);
this.assertHelper.AssertNetworkStatus("@replaceLayoutWithCRUDPage", 201);
this.agHelper.GetNClick(this.locator._visibleTextSpan("Got it"));
}
public GeneratePageWithMockDB() {
this.ee.AddNewPage("Generate page with data");
this.agHelper.GetNClick(this._selectDatasourceDropdown);
this.agHelper.GetNClickByContains(
this._dropdownOption,
"Connect new datasource",
);
this.agHelper.GetNClick(this._mockDB("Users"));
this.agHelper.Sleep(500);
this.assertHelper.AssertNetworkStatus("@getDatasourceStructure"); //Making sure table dropdown is populated
this.agHelper.GetNClick(this._selectTableDropdown, 0, true);
this.agHelper.GetNClickByContains(this._dropdownOption, "public.users");
this.agHelper.GetNClick(this._generatePageBtn);
this.assertHelper.AssertNetworkStatus("@replaceLayoutWithCRUDPage", 201);
this.agHelper.GetNClick(this.locator._visibleTextSpan("Got it"));
}
public StartDataSourceRoutes() {
cy.intercept("POST", "/api/v1/datasources").as("saveDatasource");
cy.intercept("POST", "/api/v1/datasources/test").as("testDatasource");
cy.intercept("PUT", "/api/v1/datasources/*").as("updateDatasource");
}
private ReplaceApplicationIdForInterceptPages(fixtureFile: any) {
let currentAppId, currentURL;
cy.readFile(
fixtureFile,
// (err: string) => {
// if (err) {
// return console.error(err);
// }}
).then((data) => {
cy.url().then((url) => {
currentURL = url;
const myRegexp = /applications(.*)/;
const match = myRegexp.exec(currentURL);
cy.log(currentURL + "currentURL from intercept is");
currentAppId = match ? match[1].split("/")[1] : null;
data.data.page.applicationId = currentAppId;
cy.writeFile(fixtureFile, JSON.stringify(data));
});
});
}
public StartInterceptRoutesForMySQL() {
//All stubbing - updating app id to current app id for Delete app by api call to be successfull:
this.ReplaceApplicationIdForInterceptPages(
"cypress/fixtures/mySQL_PUT_replaceLayoutWithCRUD.json",
);
cy.intercept("POST", "/api/v1/datasources/test", {
fixture: "testAction.json",
}).as("testDatasource");
cy.intercept("GET", "/api/v1/datasources/*/structure?ignoreCache=*", {
fixture: "mySQL_GET_selectTableDropdown.json",
}).as("getDatasourceStructure");
cy.intercept("PUT", "/api/v1/pages/crud-page/*", {
fixture: "mySQL_PUT_replaceLayoutWithCRUD.json",
}).as("replaceLayoutWithCRUDPage");
cy.intercept("GET", "/api/v1/actions*", {
fixture: "mySQL_GET_Actions.json",
}).as("getActions");
cy.intercept("POST", "/api/v1/actions/execute", {
fixture: "mySQL_POST_Execute.json",
}).as("postExecute");
cy.intercept("POST", "/api/v1/pages/crud-page", {
fixture: "mySQL_PUT_replaceLayoutWithCRUD.json",
}).as("replaceLayoutWithCRUDPage");
}
public StartInterceptRoutesForMongo() {
//All stubbing
this.ReplaceApplicationIdForInterceptPages(
"cypress/fixtures/mongo_PUT_replaceLayoutWithCRUD.json",
);
cy.intercept("POST", "/api/v1/datasources/test", {
fixture: "testAction.json",
}).as("testDatasource");
cy.intercept("GET", "/api/v1/datasources/*/structure?ignoreCache=*", {
fixture: "mongo_GET_selectTableDropdown.json",
}).as("getDatasourceStructure");
cy.intercept("PUT", "/api/v1/pages/crud-page/*", {
fixture: "mongo_PUT_replaceLayoutWithCRUD.json",
}).as("replaceLayoutWithCRUDPage");
cy.intercept("GET", "/api/v1/actions*", {
fixture: "mongo_GET_Actions.json",
}).as("getActions");
cy.intercept("POST", "/api/v1/actions/execute", {
fixture: "mongo_POST_Actions.json",
}).as("postExecute");
cy.intercept("POST", "/api/v1/pages/crud-page", {
fixture: "mongo_PUT_replaceLayoutWithCRUD.json",
}).as("post_replaceLayoutCRUDStub");
}
public StartInterceptRoutesForFirestore() {
//All stubbing
cy.intercept("POST", "/api/v1/datasources/test", {
fixture: "testAction.json",
}).as("testDatasource");
}
public CreatePlugIn(pluginName: string, waitForToastDisappear = false) {
cy.get(this._createNewPlgin(pluginName))
.parent("div")
.trigger("click", { force: true });
this.agHelper.Sleep();
//this.agHelper.WaitUntilEleAppear(this.locator._toastMsg);
this.agHelper.AssertElementAbsence(
this.locator._specificToast("Duplicate key error"),
);
this.agHelper.PressEscape();
// if (waitForToastDisappear)
// this.agHelper.WaitUntilToastDisappear("datasource created");
// else this.agHelper.AssertContains("datasource created");
}
public EditDatasource() {
this.agHelper.GetNClick(this._editButton);
}
public ExpandSection(index: number) {
cy.get(this._collapseContainer).eq(index).click();
cy.get(this._collapseSettings).should("be.visible");
}
public ExpandSectionByName(sectionName: string) {
// Click on collapse section only if it collapsed, if it is expanded we ignore
this.agHelper
.GetElement(this._sectionState(sectionName))
.invoke("attr", "aria-hidden")
.then((hidden: any) => {
if (hidden == "true") {
this.agHelper.GetNClick(this._section(sectionName));
}
});
}
public AssertSectionCollapseState(index: number, collapsed = false) {
if (collapsed) {
cy.get(this._collapseSettings).should("not.be.visible");
} else {
cy.get(this._collapseSettings).should("be.visible");
}
}
public NavigateToDSCreateNew() {
this.ee.HoverOnEntityItem("Datasources");
Cypress._.times(2, () => {
this.agHelper.GetNClick(this._addNewDataSource, 0, true);
this.agHelper.Sleep();
});
this.agHelper.RemoveTooltip("Add a new datasource");
cy.get(this._newDatasourceContainer).scrollTo("bottom", {
ensureScrollable: false,
});
cy.get(this._newDatabases).should("be.visible");
}
CreateMockDB(dbName: "Users" | "Movies"): Cypress.Chainable<string> {
this.NavigateToDSCreateNew();
this.agHelper.GetNClick(this._mockDB(dbName));
this.assertHelper.AssertNetworkStatus("@getMockDb"); //To return the right mock DB name
return cy
.get("@getMockDb")
.then(($createdMock: any) => $createdMock.response?.body.data.name);
}
public FillPostgresDSForm(
shouldAddTrailingSpaces = false,
username = "",
password = "",
) {
const hostAddress = shouldAddTrailingSpaces
? this.hp.postgres_host + " "
: this.hp.postgres_host;
const databaseName = shouldAddTrailingSpaces
? this.hp.postgres_databaseName + " "
: this.hp.postgres_databaseName;
this.agHelper.UpdateInputValue(
this._port,
this.hp.postgres_port.toString(),
);
this.agHelper.UpdateInputValue(this._host, hostAddress);
cy.get(this._databaseName).clear().type(databaseName);
this.ExpandSectionByName("Authentication");
cy.get(this._username).type(
username == "" ? this.hp.postgres_username : username,
);
cy.get(this._password).type(
password == "" ? this.hp.postgres_username : password,
);
}
public FillOracleDSForm(
shouldAddTrailingSpaces = false,
username = "",
password = "",
) {
const hostAddress = shouldAddTrailingSpaces
? this.hp.oracle_host + " "
: this.hp.oracle_host;
const databaseName = shouldAddTrailingSpaces
? this.hp.oracle_name + " "
: this.hp.oracle_name;
this.agHelper.UpdateInputValue(this._host, hostAddress);
this.agHelper.UpdateInputValue(this._port, this.hp.oracle_port.toString());
cy.get(this._databaseName).clear().type(databaseName);
this.ExpandSectionByName("Authentication");
cy.get(this._username).type(
username == "" ? this.hp.oracle_username : username,
);
cy.get(this._password).type(
password == "" ? this.hp.oracle_password : password,
);
}
public FillMongoDSForm(shouldAddTrailingSpaces = false) {
const hostAddress = shouldAddTrailingSpaces
? this.hp.mongo_host + " "
: this.hp.mongo_host;
this.agHelper.UpdateInputValue(this._host, hostAddress);
this.agHelper.UpdateInputValue(this._port, this.hp.mongo_port.toString());
this.ExpandSectionByName("Authentication");
cy.get(this._databaseName).clear().type(this.hp.mongo_databaseName);
}
public FillMySqlDSForm(shouldAddTrailingSpaces = false) {
const hostAddress = shouldAddTrailingSpaces
? this.hp.mysql_host + " "
: this.hp.mysql_host;
const databaseName = shouldAddTrailingSpaces
? this.hp.mysql_databaseName + " "
: this.hp.mysql_databaseName;
this.agHelper.UpdateInputValue(this._host, hostAddress);
this.agHelper.UpdateInputValue(this._port, this.hp.mysql_port.toString());
cy.get(this._databaseName).clear().type(databaseName);
this.ExpandSectionByName("Authentication");
cy.get(this._username).type(this.hp.mysql_username);
cy.get(this._password).type(this.hp.mysql_password);
}
public FillMsSqlDSForm() {
this.agHelper.UpdateInputValue(this._host, this.hp.mssql_host);
this.agHelper.UpdateInputValue(this._port, this.hp.mssql_port.toString());
this.agHelper.ClearTextField(this._databaseName);
// this.agHelper.UpdateInputValue(
// this._databaseName,
// datasourceFormData["mssql-databaseName"],
// ); //Commenting until MsSQL is init loaded into container
this.ExpandSectionByName("Authentication");
this.agHelper.UpdateInputValue(this._username, this.hp.mssql_username);
this.agHelper.UpdateInputValue(this._password, this.hp.mssql_password);
}
public FillAirtableDSForm() {
this.ValidateNSelectDropdown(
"Authentication type",
"Please select an option",
"Personal access token",
);
this.agHelper.UpdateInput(
this.locator._inputFieldByName("Bearer token"),
Cypress.env("AIRTABLE_BEARER"),
);
this.agHelper.Sleep();
}
public FillArangoDSForm() {
this.agHelper.UpdateInputValue(this._host, this.hp.arango_host);
this.agHelper.UpdateInputValue(this._port, this.hp.arango_port.toString());
//Validating db name is _system, currently unable to create DB via curl in Arango
this.agHelper
.GetText(this._databaseName, "val")
.then(($dbName) => expect($dbName).to.eq("_system"));
this.ExpandSectionByName("Authentication");
this.agHelper.UpdateInputValue(this._username, this.hp.arango_username);
this.agHelper.UpdateInputValue(this._password, this.hp.arango_password);
}
public FillCurlNImport(value: string) {
this.NavigateToDSCreateNew();
this.agHelper.GetNClick(this._createBlankCurl);
this.ImportCurlNRun(value);
}
public ImportCurlNRun(value: string) {
this.agHelper.UpdateTextArea(this._curlTextArea, value);
this.agHelper.Sleep(500); //Clicking import after value settled
this.agHelper.ClickButton("Import");
this.apiPage.RunAPI();
}
public FillFirestoreDSForm() {
this.agHelper.UpdateInput(
this.locator._inputFieldByName("Database URL"),
this.hp.firestore_database_url,
);
this.agHelper.UpdateInput(
this.locator._inputFieldByName("Project Id"),
this.hp.firestore_projectID,
);
// cy.fixture("firestore-ServiceAccCreds").then((json: any) => {
// let ServiceAccCreds = JSON.parse(
// JSON.stringify(json.serviceAccCredentials),
// );
// ServiceAccCreds.private_key = Cypress.env("FIRESTORE_PRIVATE_KEY");
// //cy.log("ServiceAccCreds is " + JSON.stringify(ServiceAccCreds));
// cy.log(
// "ServiceAccCreds.private_key is " +
// JSON.stringify(ServiceAccCreds.private_key),
// );
this.agHelper.UpdateFieldLongInput(
this.locator._inputFieldByName("Service account credentials"),
JSON.stringify(Cypress.env("FIRESTORE_PRIVATE_KEY")),
);
//});
}
public FillElasticSearchDSForm() {
this.agHelper.UpdateInputValue(this._host, this.hp.elastic_host);
this.agHelper.UpdateInputValue(this._port, this.hp.elastic_port.toString());
this.ExpandSectionByName("Authentication");
this.agHelper.UpdateInputValue(this._username, this.hp.elastic_username);
this.agHelper.UpdateInputValue(this._password, this.hp.elastic_password);
}
public FillUnAuthenticatedGraphQLDSForm() {
this.agHelper.GetNClick(this._createBlankGraphQL);
this.apiPage.EnterURL(this.hp.GraphqlApiUrl_TED);
this.assertHelper.AssertNetworkStatus("@createNewApi", 201);
}
public CreateNFillAuthenticatedGraphQLDSForm(
dataSourceName: string,
hKey: string,
hValue: string,
) {
this.NavigateToDSCreateNew();
this.CreatePlugIn("Authenticated GraphQL API");
this.agHelper.UpdateInput(
this.locator._inputFieldByName("URL"),
this.hp.GraphqlApiUrl_TED,
);
this.agHelper.UpdateInputValue(this._graphQLHeaderKey, hKey);
this.agHelper.UpdateInputValue(this._graphQLHeaderValue, hValue);
cy.get("@guid").then((uid: any) => {
dataSourceName = dataSourceName + " " + uid;
this.agHelper.RenameWithInPane(dataSourceName, false);
this.SaveDatasource();
cy.wrap(dataSourceName).as("dsName");
});
}
public FillRedisDSForm() {
this.agHelper.UpdateInputValue(this._host, this.hp.redis_host);
this.agHelper.UpdateInputValue(this._port, this.hp.redis_port.toString());
}
public TestSaveDatasource(expectedRes = true) {
this.TestDatasource(expectedRes);
this.SaveDatasource();
}
public TestDatasource(expectedRes = true) {
this.agHelper.GetNClick(this._testDs, 0, false, 0);
this.agHelper.AssertNetworkDataSuccess("@testDatasource", expectedRes);
if (expectedRes) {
this.agHelper.AssertContains("datasource is valid");
}
}
public SaveDatasource() {
this.agHelper.GetNClick(this._saveDs);
this.assertHelper.AssertNetworkStatus("@saveDatasource", 201);
this.agHelper.AssertContains("datasource created");
// cy.wait("@saveDatasource")
// .then((xhr) => {
// cy.log(JSON.stringify(xhr.response!.body));
// }).should("have.nested.property", "response.body.responseMeta.status", 200);
}
public AuthAPISaveAndAuthorize() {
cy.get(this._saveAndAuthorizeDS).click();
this.assertHelper.AssertNetworkStatus("@saveDatasource", 201);
}
public UpdateDatasource() {
this.agHelper.GetNClick(this._saveDs);
// this.assertHelper.AssertNetworkStatus("@updateDatasource", 200);
this.agHelper.AssertContains("datasource updated");
}
public ClickActiveTabDSContextMenu(datasourceName: string) {
this.NavigateToActiveTab();
cy.get(this._datasourceCard)
.contains(datasourceName)
.parents(this._datasourceCard)
.find(this._dsMenuoptions)
.scrollIntoView()
.should("be.visible")
.click();
}
public DeleteDatasouceFromActiveTab(
datasourceName: string,
expectedRes = 200 || 409 || [200 | 409],
) {
this.ClickActiveTabDSContextMenu(datasourceName);
this.agHelper.GetNClick(this._dsOptionMenuItem("Delete"), 0, false, 200);
this.agHelper.GetNClick(this._dsOptionMenuItem("Are you sure?"));
this.ValidateDSDeletion(expectedRes);
}
public DeleteDatasouceFromWinthinDS(
datasourceName: string,
expectedRes: number | number[] = 200 || 409 || [200 | 409],
) {
this.NavigateToActiveTab();
cy.get(this._datasourceCard)
.contains(datasourceName)
.scrollIntoView()
.should("be.visible")
.click();
this.agHelper.Sleep(); //for the Datasource page to open
this.DeleteDSDirectly(expectedRes);
}
public DeleteDSDirectly(
expectedRes: number | number[] = 200 || 409 || [200 | 409],
) {
this.agHelper.GetNClick(this._cancelEditDatasourceButton, 0, false, 200);
cy.get(this._contextMenuDSReviewPage).click({ force: true });
this.agHelper.GetNClick(this._contextMenuDelete);
this.agHelper.GetNClick(this.locator._visibleTextSpan("Are you sure?"));
this.ValidateDSDeletion(expectedRes);
}
public DeleteDSFromEntityExplorer(
dsName: string,
expectedRes: number | number[] = 200,
) {
this.ee.SelectEntityByName(dsName, "Datasources");
this.ee.ActionContextMenuByEntityName({
entityNameinLeftSidebar: dsName,
action: "Delete",
entityType: EntityItems.Datasource,
});
this.ValidateDSDeletion(expectedRes);
}
public ValidateDSDeletion(expectedRes: number | number[] = 200) {
let toValidateRes = expectedRes == 200 || expectedRes == 409 ? true : false;
if (toValidateRes) {
if (expectedRes == 200)
this.agHelper.AssertContains("datasource deleted successfully");
else this.agHelper.AssertContains("action(s) using it.");
this.assertHelper.AssertNetworkStatus(
"@deleteDatasource",
expectedRes as number,
);
} else {
cy.wait("@deleteDatasource")
.its("response.body.responseMeta.status")
.should("be.oneOf", [200, 409]);
}
}
public NavigateToActiveTab() {
this.agHelper.GetElement(this.locator._body).then(($body) => {
if ($body.find(this._selectedActiveTab).length == 0) {
this.NavigateToDSCreateNew();
this.agHelper.GetNClick(this._activeTab, 0, true);
}
});
}
public NavigateFromActiveDS(datasourceName: string, createQuery: boolean) {
const btnLocator =
createQuery == true
? this._createQuery
: this._datasourceCardGeneratePageBtn;
this.AssertDSActive(datasourceName)
.scrollIntoView()
.should("be.visible")
.closest(this._datasourceCard)
.within(() => {
this.agHelper.GetNClick(btnLocator, 0, true);
});
this.agHelper.Sleep(3000); //for the CreateQuery/GeneratePage page to load
createQuery &&
this.agHelper.AssertElementVisible(
this.locator._spanButton("Run"),
0,
20000,
);
!createQuery &&
this.assertHelper.AssertNetworkStatus("@getDatasourceStructure", 200); //Making sure table dropdown is populated
}
public AssertDSActive(dsName: string) {
this.ee.NavigateToSwitcher("Explorer", 0, true);
this.ee.ExpandCollapseEntity("Datasources", false);
//this.ee.SelectEntityByName(datasourceName, "Datasources");
//this.ee.ExpandCollapseEntity(datasourceName, false);
this.NavigateToActiveTab();
return this.agHelper.GetNAssertContains(this._datasourceCard, dsName);
}
public CreateQueryFromActiveTab(
datasourceName: string,
toNavigateToActive = true,
) {
if (toNavigateToActive) this.NavigateToActiveTab();
cy.get(this._datasourceCard, { withinSubject: null })
.find(this._activeDS)
.contains(datasourceName)
.scrollIntoView()
.should("be.visible")
.closest(this._datasourceCard)
.scrollIntoView()
.within(() => {
this.agHelper.GetNClick(this._createQuery, 0, true);
});
this.agHelper.Sleep(2000); //for the CreateQuery
//this.assertHelper.AssertNetworkStatus("@createNewApi", 201);//throwing 404 in CI sometimes
this.agHelper.AssertElementVisible(
this.locator._spanButton("Run"),
0,
20000,
);
}
CreateQueryAfterDSSaved(query = "", queryName = "") {
this.agHelper.GetNClick(this._createQuery);
//this.assertHelper.AssertNetworkStatus("@createNewApi", 201);
this.agHelper.AssertElementVisible(
this.locator._spanButton("Run"),
0,
20000,
);
if (queryName) this.agHelper.RenameWithInPane(queryName);
if (query) {
this.EnterQuery(query);
}
}
DeleteQuery(queryName: string) {
this.ee.ExpandCollapseEntity("Queries/JS");
this.ee.ActionContextMenuByEntityName({
entityNameinLeftSidebar: queryName,
action: "Delete",
entityType: EntityItems.Query,
});
}
public ValidateNSelectDropdown(
ddTitle: string,
currentValue: string,
newValue = "",
) {
if (currentValue)
cy.xpath(this._visibleTextSpan(currentValue))
//.scrollIntoView()
.should("exist", currentValue + " dropdown value not present");
if (newValue != "") {
this.agHelper.GetNClick(this._dropdownTitle(ddTitle));
//cy.xpath(this._dropdown(currentValue)).last().click({ force: true });
//to expand the dropdown
//this.agHelper.GetNClick(this._queryOption(newValue))
cy.xpath(this._queryOption(newValue)).last().click({ force: true }); //to select the new value
}
}
public ReconnectDataSource(dbName: string, dsName: "PostgreSQL" | "MySQL") {
this.agHelper.AssertElementVisible(this._reconnectModal);
this.agHelper.AssertElementVisible(this._testDs); //Making sure modal is fully loaded
cy.xpath(this._activeDSListReconnectModal(dsName)).should("be.visible");
cy.xpath(this._activeDSListReconnectModal(dbName)).should("be.visible"); //.click()
this.ValidateNSelectDropdown("Connection mode", "Read / Write");
if (dsName == "PostgreSQL") this.FillPostgresDSForm();
else if (dsName == "MySQL") this.FillMySqlDSForm();
cy.get(this._saveDs).click();
}
RunQuery({
expectedStatus = true,
toValidateResponse = true,
waitTimeInterval = 500,
}: Partial<RunQueryParams> = {}) {
this.agHelper.GetNClick(this._runQueryBtn, 0, true, waitTimeInterval);
this.agHelper.AssertElementAbsence(
this.locator._cancelActionExecution,
10000,
); //For the run to give response
if (toValidateResponse) {
this.agHelper.Sleep();
this.agHelper.AssertNetworkExecutionSuccess(
"@postExecute",
expectedStatus,
);
}
}
AssertRunButtonDisability(disabled = false) {
let query = "";
if (disabled) {
query = "be.disabled";
} else {
query = "not.be.disabled";
}
cy.get(this._runQueryBtn).should(query);
}
public ReadQueryTableResponse(index: number, timeout = 100) {
//timeout can be sent higher values incase of larger tables
this.agHelper.Sleep(timeout); //Settling time for table!
return cy.xpath(this._queryTableResponse).eq(index).invoke("text");
}
public AssertQueryResponseHeaders(columnHeaders: string[]) {
columnHeaders.forEach(($header) =>
this.agHelper.AssertElementVisible(this._queryResponseHeader($header)),
);
}
public AssertJSONFormHeader(
rowindex: number,
colIndex: number,
headerString: string,
validateCellData: "" | string = "",
isMongo = false,
) {
let jsonHeaderString = "";
this.table.ReadTableRowColumnData(rowindex, colIndex).then(($cellData) => {
if (validateCellData) expect($cellData).to.eq(validateCellData);
jsonHeaderString =
isMongo == true
? "Update Document " + headerString + ": " + $cellData
: "Update Row " + headerString + ": " + $cellData;
this.agHelper
.GetText(this.locator._jsonFormHeader)
.then(($header: any) => expect($header).to.eq(jsonHeaderString));
});
}
public ToggleUsePreparedStatement(enable = true || false) {
if (enable)
cy.get(this._usePreparedStatement).check({
force: true,
});
else
cy.get(this._usePreparedStatement).uncheck({
force: true,
});
this.agHelper.AssertAutoSave();
}
public EnterQuery(query: string, sleep = 500) {
this.agHelper.UpdateCodeInput(this.locator._codeEditorTarget, query);
this.agHelper.AssertAutoSave();
this.agHelper.Sleep(sleep); //waiting a bit before proceeding!
cy.wait("@saveAction");
}
public RunQueryNVerifyResponseViews(
expectedRecordsCount = 1,
tableCheck = true,
) {
this.RunQuery();
tableCheck &&
this.agHelper.AssertElementVisible(this._queryResponse("TABLE"));
this.agHelper.AssertElementVisible(this._queryResponse("JSON"));
this.agHelper.AssertElementVisible(this._queryResponse("RAW"));
this.CheckResponseRecordsCount(expectedRecordsCount);
}
public CheckResponseRecordsCount(expectedRecordCount: number) {
this.agHelper.AssertElementVisible(
this._queryRecordResult(expectedRecordCount),
);
}
public CreateDataSource(
dsType:
| "Postgres"
| "Mongo"
| "MySql"
| "UnAuthenticatedGraphQL"
| "MsSql"
| "Airtable"
| "Arango"
| "Firestore"
| "Elasticsearch"
| "Redis"
| "Oracle",
navigateToCreateNewDs = true,
testNSave = true,
) {
let guid: any;
let dataSourceName = "";
this.agHelper.GenerateUUID();
navigateToCreateNewDs && this.NavigateToDSCreateNew();
cy.get("@guid").then((uid) => {
if (DataSourceKVP[dsType] != "GraphQL API") {
this.CreatePlugIn(DataSourceKVP[dsType]);
guid = uid;
dataSourceName = dsType + " " + guid;
this.agHelper.RenameWithInPane(dataSourceName, false);
if (DataSourceKVP[dsType] == "PostgreSQL") this.FillPostgresDSForm();
else if (DataSourceKVP[dsType] == "Oracle") this.FillOracleDSForm();
else if (DataSourceKVP[dsType] == "MySQL") this.FillMySqlDSForm();
else if (DataSourceKVP[dsType] == "MongoDB") this.FillMongoDSForm();
else if (DataSourceKVP[dsType] == "Microsoft SQL Server")
this.FillMsSqlDSForm();
else if (DataSourceKVP[dsType] == "Airtable") this.FillAirtableDSForm();
else if (DataSourceKVP[dsType] == "ArangoDB") this.FillArangoDSForm();
else if (DataSourceKVP[dsType] == "Firestore")
this.FillFirestoreDSForm();
else if (DataSourceKVP[dsType] == "Elasticsearch")
this.FillElasticSearchDSForm();
else if (DataSourceKVP[dsType] == "Redis") this.FillRedisDSForm();
if (testNSave) {
this.TestSaveDatasource();
} else {
this.SaveDatasource();
}
} else if (DataSourceKVP[dsType] == "GraphQL API")
this.FillUnAuthenticatedGraphQLDSForm();
cy.wrap(dataSourceName).as("dsName");
});
}
public CreateQueryFromOverlay(
dsName: string,
query = "",
queryName = "",
sleep = 500,
) {
this.agHelper.RemoveEvaluatedPopUp(); //to close the evaluated pop-up
this.ee.CreateNewDsQuery(dsName);
if (query) {
this.EnterQuery(query, sleep);
}
if (queryName) this.agHelper.RenameWithInPane(queryName);
}
public UpdateGraphqlQueryAndVariable(options?: {
query?: string;
variable?: string;
}) {
if (options?.query) {
this.agHelper.UpdateCodeInput(this._graphqlQueryEditor, options.query);
}
if (options?.variable) {
this.agHelper.UpdateCodeInput(
this._graphqlVariableEditor,
options.variable as string,
);
}
this.agHelper.Sleep();
}
public UpdateGraphqlPaginationParams(options: {
limit?: {
variable: string;
value: any;
};
offset?: {
variable: string;
value: any;
};
}) {
if (options.limit) {
// Select Limit variable from dropdown
cy.get(this._graphqlPagination._limitVariable).click({
force: true,
});
cy.get(".rc-select-item-option")
.contains(options.limit.variable)
.click({ force: true });
// Set the Limit value as 1
cy.get(this._graphqlPagination._limitValue)
.first()
.focus()
.type(options.limit.value);
}
if (options.offset) {
// Select Offset vaiable from dropdown
cy.get(this._graphqlPagination._offsetVariable).click({
force: true,
});
cy.get(".rc-select-item-option")
.eq(2)
.contains(options.offset.variable)
.click({ force: true });
// Set the Limit value as 1
cy.get(this._graphqlPagination._offsetValue)
.first()
.focus()
.type(options.offset.value);
}
this.agHelper.Sleep();
}
public SetQueryTimeout(queryTimeout = 20000) {
this.agHelper.GetNClick(this._queryEditorTabs("Settings"));
cy.xpath(this._queryTimeout)
.clear()
.type(queryTimeout.toString(), { delay: 0 }); //Delay 0 to work like paste!
this.agHelper.AssertAutoSave();
this.agHelper.GetNClick(this._queryEditorTabs("Query"));
}
//Update with new password in the datasource conf page
public UpdatePassword(newPassword: string) {
this.ExpandSectionByName("Authentication");
cy.get(this._password).type(newPassword);
}
//Fetch schema from server and validate UI for the updates
public VerifySchema(
dataSourceName: string,
schema: string,
isUpdate = false,
) {
cy.intercept("GET", this._getStructureReq).as("getDSStructure");
if (isUpdate) {
this.UpdateDatasource();
} else {
this.SaveDatasource();
}
this.ee.ActionContextMenuByEntityName({
entityNameinLeftSidebar: dataSourceName,
action: "Refresh",
});
cy.wait("@getDSStructure").then(() => {
cy.get(".bp3-collapse-body").contains(schema);
});
}
public SaveDSFromDialog(save = true) {
this.agHelper.GoBack();
this.agHelper.AssertElementVisible(this._datasourceModalDoNotSave);
this.agHelper.AssertElementVisible(this._datasourceModalSave);
if (save) {
this.agHelper.GetNClick(
this.locator._visibleTextSpan("Save"),
0,
true,
0,
);
this.assertHelper.AssertNetworkStatus("@saveDatasource", 201);
this.agHelper.AssertContains("datasource created");
} else
this.agHelper.GetNClick(
this.locator._visibleTextSpan("Don't save"),
0,
true,
0,
);
}
public getDSEntity(dSName: string) {
return `[data-guided-tour-id="explorer-entity-${dSName}"]`;
}
public FillAuthAPIUrl() {
this.agHelper.UpdateInput(
this.locator._inputFieldByName("URL"),
this.hp.authenticatedApiUrl,
);
}
public AssertCursorPositionForTextInput(
selector: string,
moveCursor: string,
typeText = "as",
cursorPosition = 0,
) {
this.agHelper
.GetElement(selector)
.type(moveCursor)
.type(typeText)
.should("have.prop", "selectionStart", cursorPosition);
}
public AddOAuth2AuthorizationCodeDetails(
accessTokenUrl: string,
clientId: string,
clientSecret: string,
authURL: string,
) {
this.agHelper.GetNClick(this._authType);
this.agHelper.GetNClick(this._oauth2);
this.agHelper.GetNClick(this._grantType);
this.agHelper.GetNClick(this._authorizationCode);
this.agHelper.TypeText(this._accessTokenUrl, accessTokenUrl);
this.agHelper.TypeText(this._clientID, clientId);
this.agHelper.TypeText(this._clientSecret, clientSecret);
this.agHelper.TypeText(this._authorizationURL, authURL);
}
public EditDSFromActiveTab(dsName: string) {
this.agHelper.GetNClick(this._editDatasourceFromActiveTab(dsName));
}
public FillMongoDatasourceFormWithURI(uri: string) {
this.ValidateNSelectDropdown(
"Use mongo connection string URI",
"No",
"Yes",
);
this.agHelper.UpdateInputValue(
this.locator._inputFieldByName("Connection string URI") + "//input",
uri,
);
}
public CreateOAuthClient(grantType: string) {
let clientId, clientSecret;
// Login to TED OAuth
let formData = new FormData();
formData.append("username", this.hp.OAuth_Username);
cy.request("POST", this.hp.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", this.hp.OAuth_RedirectUrl);
clientData.append("grant_type", grantType);
clientData.append("response_type", "code");
clientData.append("token_endpoint_auth_method", "client_secret_post");
cy.request("POST", this.hp.OAuth_Host + "/create_client", clientData).then(
(response) => {
expect(response.status).to.equal(200);
},
);
// Get Client Credentials
cy.request("GET", this.hp.OAuth_Host).then((response) => {
clientId = response.body.split("client_id: </strong>");
clientId = clientId[1].split("<strong>client_secret: </strong>");
clientSecret = clientId[1].split("<strong>");
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
this.agHelper.GetNClick(this._authApiDatasource, 0, 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.assertHelper.AssertNetworkStatus("@saveDatasource", 201);
}
public FillAPIOAuthForm(
dsName: string,
grantType: "ClientCredentials" | "AuthCode",
clientId: string,
clientSecret: string,
) {
if (dsName) this.agHelper.RenameWithInPane(dsName, false);
// Fill Auth Form
this.agHelper.UpdateInput(
this.locator._inputFieldByName("URL"),
this.hp.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"),
this.hp.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"),
this.hp.OAuth_AuthUrl,
);
}
public AddSuggesstedWidget(widget: Widgets) {
switch (widget) {
case Widgets.Dropdown:
this.agHelper.GetNClick(this._suggestedWidget("SELECT_WIDGET"));
this.agHelper.AssertElementVisible(
this.locator._widgetInCanvas(WIDGET.SELECT),
);
break;
case Widgets.Table:
this.agHelper.GetNClick(this._suggestedWidget("TABLE_WIDGET_V2"));
this.agHelper.AssertElementVisible(
this.locator._widgetInCanvas(WIDGET.TABLE),
);
break;
case Widgets.Chart:
this.agHelper.GetNClick(this._suggestedWidget("CHART_WIDGET"));
this.agHelper.AssertElementVisible(
this.locator._widgetInCanvas(WIDGET.CHART),
);
break;
case Widgets.Text:
this.agHelper.GetNClick(this._suggestedWidget("TEXT_WIDGET"));
this.agHelper.AssertElementVisible(
this.locator._widgetInCanvas(WIDGET.TEXT),
);
break;
}
}
public EnterJSContext({
fieldLabel,
fieldProperty,
fieldValue,
}: {
fieldProperty: string;
fieldValue: string;
fieldLabel: string;
}) {
this.agHelper.Sleep();
this.agHelper
.GetElement(this._getJSONswitchLocator(fieldProperty))
.invoke("attr", "data-selected")
.then(($state: any) => {
if (!$state.includes("true"))
this.agHelper.GetNClick(
this._getJSONswitchLocator(fieldProperty),
0,
true,
);
else this.agHelper.Sleep(200);
});
this.agHelper.EnterValue(fieldValue, {
propFieldName: "",
directInput: false,
inputFieldName: fieldLabel,
});
}
}