2022-05-18 10:39:42 +00:00
|
|
|
import { ObjectsRegistry } from "../Objects/Registry";
|
2023-03-16 18:28:32 +00:00
|
|
|
import { WIDGET } from "../../locators/WidgetLocators";
|
2023-06-15 13:21:11 +00:00
|
|
|
import { EntityItems } from "./AssertHelper";
|
2023-11-23 10:16:13 +00:00
|
|
|
import EditorNavigation, {
|
2023-11-28 11:11:54 +00:00
|
|
|
AppSidebar,
|
2023-12-05 05:50:36 +00:00
|
|
|
AppSidebarButton,
|
|
|
|
|
EntityType,
|
2023-11-29 11:11:33 +00:00
|
|
|
PageLeftPane,
|
2024-01-12 14:43:58 +00:00
|
|
|
PagePaneSegment,
|
2023-11-23 10:16:13 +00:00
|
|
|
} from "./EditorNavigation";
|
2023-11-15 02:31:12 +00:00
|
|
|
import datasource from "../../locators/DatasourcesEditor.json";
|
2023-11-29 11:11:33 +00:00
|
|
|
import PageList from "./PageList";
|
2024-05-30 07:16:56 +00:00
|
|
|
import { anvilLocators } from "./Anvil/Locators";
|
2024-12-03 03:51:43 +00:00
|
|
|
import { PluginActionForm } from "./PluginActionForm";
|
|
|
|
|
import ApiEditor from "../../locators/ApiEditor";
|
2024-12-03 09:34:54 +00:00
|
|
|
import BottomTabs from "./IDE/BottomTabs";
|
2022-07-29 08:48:25 +00:00
|
|
|
|
2023-08-18 05:18:35 +00:00
|
|
|
export const DataSourceKVP = {
|
2022-07-29 08:48:25 +00:00
|
|
|
Postgres: "PostgreSQL",
|
|
|
|
|
Mongo: "MongoDB",
|
|
|
|
|
MySql: "MySQL",
|
2023-03-15 05:03:34 +00:00
|
|
|
UnAuthenticatedGraphQL: "GraphQL API",
|
2023-09-04 13:30:21 +00:00
|
|
|
AuthenticatedGraph: "Authenticated GraphQL API",
|
2023-03-16 18:28:32 +00:00
|
|
|
MsSql: "Microsoft SQL Server",
|
2023-03-18 19:42:01 +00:00
|
|
|
Airtable: "Airtable",
|
2023-07-21 05:53:17 +00:00
|
|
|
ArangoDB: "ArangoDB",
|
2023-04-04 15:56:57 +00:00
|
|
|
Firestore: "Firestore",
|
2023-04-06 04:07:04 +00:00
|
|
|
Elasticsearch: "Elasticsearch",
|
2023-04-25 18:24:36 +00:00
|
|
|
Redis: "Redis",
|
2023-06-12 17:48:46 +00:00
|
|
|
Oracle: "Oracle",
|
2023-06-30 18:46:57 +00:00
|
|
|
S3: "S3",
|
2023-08-22 17:22:36 +00:00
|
|
|
Twilio: "Twilio",
|
2023-09-08 09:12:27 +00:00
|
|
|
SMTP: "SMTP",
|
2022-08-04 04:48:15 +00:00
|
|
|
}; //DataSources KeyValuePair
|
2022-07-29 08:48:25 +00:00
|
|
|
|
2023-03-16 18:28:32 +00:00
|
|
|
export enum Widgets {
|
|
|
|
|
Dropdown,
|
|
|
|
|
Table,
|
|
|
|
|
Chart,
|
|
|
|
|
Text,
|
2024-01-31 05:32:38 +00:00
|
|
|
WDSTable,
|
2023-03-16 18:28:32 +00:00
|
|
|
}
|
2024-07-10 08:52:39 +00:00
|
|
|
|
2023-11-03 06:57:24 +00:00
|
|
|
type AppModes = "Edit" | "View";
|
2023-03-16 18:28:32 +00:00
|
|
|
|
2023-03-18 19:42:01 +00:00
|
|
|
interface RunQueryParams {
|
|
|
|
|
toValidateResponse?: boolean;
|
|
|
|
|
expectedStatus?: boolean;
|
|
|
|
|
waitTimeInterval?: number;
|
|
|
|
|
}
|
2024-07-10 08:52:39 +00:00
|
|
|
|
2022-03-02 16:54:43 +00:00
|
|
|
export class DataSources {
|
2022-05-18 10:39:42 +00:00
|
|
|
private agHelper = ObjectsRegistry.AggregateHelper;
|
2022-05-31 05:33:59 +00:00
|
|
|
private table = ObjectsRegistry.Table;
|
2023-08-04 03:46:59 +00:00
|
|
|
private entityExplorer = ObjectsRegistry.EntityExplorer;
|
2022-05-31 05:33:59 +00:00
|
|
|
private locator = ObjectsRegistry.CommonLocators;
|
2023-03-15 05:03:34 +00:00
|
|
|
private apiPage = ObjectsRegistry.ApiPage;
|
2023-08-18 05:18:35 +00:00
|
|
|
private dataManager = ObjectsRegistry.DataManager;
|
2023-06-17 08:23:03 +00:00
|
|
|
private assertHelper = ObjectsRegistry.AssertHelper;
|
2024-12-03 03:51:43 +00:00
|
|
|
private pluginActionForm = new PluginActionForm();
|
2022-05-18 10:39:42 +00:00
|
|
|
|
2023-06-21 17:37:21 +00:00
|
|
|
public ContainerKVP = (containerName: string) => {
|
|
|
|
|
return {
|
2023-08-18 05:18:35 +00:00
|
|
|
MsSql: this.dataManager.mssql_docker(containerName),
|
|
|
|
|
Arango: this.dataManager.arango_docker(containerName),
|
|
|
|
|
Elasticsearch: this.dataManager.elastic_docker(containerName),
|
2023-06-21 17:37:21 +00:00
|
|
|
};
|
|
|
|
|
}; //Container KeyValuePair
|
2023-07-26 18:13:54 +00:00
|
|
|
private _dsReviewSection = "[data-testid='t--ds-review-section']";
|
2023-11-15 02:31:12 +00:00
|
|
|
public _addNewDataSource = ".t--add-datasource-button";
|
2024-01-05 06:12:03 +00:00
|
|
|
private _addNewDatasourceFromBlankScreen =
|
2023-12-26 09:09:14 +00:00
|
|
|
".t--add-datasource-button-blank-screen";
|
2024-01-25 13:41:48 +00:00
|
|
|
public _newDatasourceBtn =
|
|
|
|
|
".t--add-datasource-button, .t--add-datasource-button-blank-screen";
|
2022-05-18 10:39:42 +00:00
|
|
|
private _createNewPlgin = (pluginName: string) =>
|
|
|
|
|
".t--plugin-name:contains('" + pluginName + "')";
|
2023-09-14 11:23:42 +00:00
|
|
|
public _host = (index = "0") =>
|
|
|
|
|
"input[name$='.datasourceConfiguration.endpoints[" + index + "].host']";
|
2023-07-03 13:06:05 +00:00
|
|
|
public _port = "input[name$='.datasourceConfiguration.endpoints[0].port']";
|
2023-07-21 05:53:17 +00:00
|
|
|
public _databaseName =
|
2023-07-03 13:06:05 +00:00
|
|
|
"input[name$='.datasourceConfiguration.authentication.databaseName']";
|
2023-07-21 05:53:17 +00:00
|
|
|
public _username =
|
2023-07-03 13:06:05 +00:00
|
|
|
"input[name$='.datasourceConfiguration.authentication.username']";
|
2023-05-19 18:37:06 +00:00
|
|
|
private _section = (name: string) =>
|
|
|
|
|
"//div[text()='" + name + "']/parent::div";
|
2023-08-08 09:14:46 +00:00
|
|
|
public _password =
|
2023-07-11 16:39:13 +00:00
|
|
|
"input[name $= '.datasourceConfiguration.authentication.password']";
|
2025-02-13 11:12:14 +00:00
|
|
|
public _testDs = ".t--test-datasource";
|
|
|
|
|
public _saveDs = ".t--save-datasource";
|
2023-01-13 11:40:58 +00:00
|
|
|
_datasourceCard = ".t--datasource";
|
2023-05-19 18:37:06 +00:00
|
|
|
_dsMenuoptions = "div.t--datasource-menu-option";
|
2022-12-08 07:21:58 +00:00
|
|
|
_editButton = ".t--edit-datasource";
|
2023-05-19 18:37:06 +00:00
|
|
|
_reconnectDataSourceModal = "[data-testid=t--tab-RECONNECT_DATASOURCES]";
|
2022-12-24 18:01:03 +00:00
|
|
|
_closeDataSourceModal = ".t--reconnect-close-btn";
|
2022-11-25 05:05:37 +00:00
|
|
|
_dsEntityItem = "[data-guided-tour-id='explorer-entity-Datasources']";
|
2023-11-15 02:31:12 +00:00
|
|
|
_activeDS = "[data-selected='true']";
|
2023-01-09 14:51:13 +00:00
|
|
|
_mockDatasourceName = "[data-testid=mockdatasource-name]";
|
2022-05-18 10:39:42 +00:00
|
|
|
_templateMenu = ".t--template-menu";
|
2024-02-13 08:22:04 +00:00
|
|
|
_bindDataButton = "[data-testid=t--bind-data]";
|
2023-09-08 07:42:48 +00:00
|
|
|
_addSuggestedExisting = "t--suggested-widget-existing";
|
|
|
|
|
_addSuggestedAddNew = "t--suggested-widget-add-new";
|
2022-07-29 08:48:25 +00:00
|
|
|
_templateMenuOption = (action: string) =>
|
|
|
|
|
"//div[contains(@class, 't--template-menu')]//div[text()='" + action + "']";
|
2023-02-02 07:59:24 +00:00
|
|
|
_createQuery = ".t--create-query";
|
2022-05-18 10:39:42 +00:00
|
|
|
_visibleTextSpan = (spanText: string) =>
|
|
|
|
|
"//span[contains(text(),'" + spanText + "')]";
|
2023-05-19 18:37:06 +00:00
|
|
|
_dsOptionMenuItem = (text: string) =>
|
|
|
|
|
"//div[@role='menuitem']//span[text()='" + text + "']";
|
2022-05-18 10:39:42 +00:00
|
|
|
_dropdownTitle = (ddTitle: string) =>
|
|
|
|
|
"//p[contains(text(),'" +
|
|
|
|
|
ddTitle +
|
2023-05-24 12:30:39 +00:00
|
|
|
"')]/ancestor::div[@class='form-config-top']/following-sibling::div[@class='t--form-control-DROP_DOWN']//input | //label[text()='" +
|
|
|
|
|
ddTitle +
|
|
|
|
|
"']/following-sibling::span//button";
|
2023-05-19 18:37:06 +00:00
|
|
|
_reconnectModal = "[data-testid='reconnect-datasource-modal']";
|
2023-07-29 00:42:08 +00:00
|
|
|
_reconnect = ".t--reconnect-btn";
|
2023-05-19 18:37:06 +00:00
|
|
|
_dropdown = (ddTitle: string) =>
|
|
|
|
|
"//span[contains(@title, '" +
|
|
|
|
|
ddTitle +
|
|
|
|
|
"') and text() = '" +
|
|
|
|
|
ddTitle +
|
|
|
|
|
"']";
|
2022-05-18 10:39:42 +00:00
|
|
|
_activeDSListReconnectModal = (dbName: string) =>
|
|
|
|
|
"//div[contains(@class, 't--ds-list')]//span[text()='" + dbName + "']";
|
2024-12-03 03:51:43 +00:00
|
|
|
_runQueryBtn = "[data-testid='t--run-action']";
|
2022-05-23 05:20:27 +00:00
|
|
|
_newDatabases = "#new-datasources";
|
2022-11-30 05:59:45 +00:00
|
|
|
_newDatasourceContainer = "#new-integrations-wrapper";
|
2023-05-19 18:37:06 +00:00
|
|
|
_selectDatasourceDropdown = "[data-testid=t--datasource-dropdown]";
|
|
|
|
|
_selectTableDropdown =
|
|
|
|
|
"[data-testid=t--table-dropdown] .rc-select-selection-item";
|
2023-08-01 11:12:44 +00:00
|
|
|
_selectSheetNameDropdown =
|
|
|
|
|
"[data-testid=t--sheetName-dropdown] .rc-select-selector";
|
2023-05-19 18:37:06 +00:00
|
|
|
_selectTableHeaderIndexInput = "[data-testid=t--tableHeaderIndex]";
|
|
|
|
|
_dropdownOption = ".rc-select-item-option-content";
|
|
|
|
|
_generatePageBtn = "[data-testid=t--generate-page-form-submit]";
|
2022-05-31 05:33:59 +00:00
|
|
|
_selectedRow = ".tr.selected-row";
|
|
|
|
|
_activeTab = "span:contains('Active')";
|
2023-09-08 09:12:27 +00:00
|
|
|
_selectedActiveTab = "button[aria-selected='true'] " + this._activeTab;
|
2023-05-29 05:40:41 +00:00
|
|
|
_contextMenuDSReviewPage = "[data-testid='t--context-menu-trigger']";
|
2023-05-22 12:05:59 +00:00
|
|
|
_contextMenuDelete = ".t--datasource-option-delete";
|
2024-01-16 08:30:51 +00:00
|
|
|
_datasourceCardGeneratePageBtn =
|
|
|
|
|
".t--generate-template, .t--datasource-generate-page";
|
2023-05-19 18:37:06 +00:00
|
|
|
_queryOption = (option: string) =>
|
|
|
|
|
"//div[contains(@class, 'rc-select-item-option-content') and text() = '" +
|
|
|
|
|
option +
|
2023-05-24 12:30:39 +00:00
|
|
|
"'] | //a[contains(@class, 'single-select')]//div[text()='" +
|
|
|
|
|
option +
|
2023-05-19 18:37:06 +00:00
|
|
|
"']";
|
2022-05-31 05:33:59 +00:00
|
|
|
_queryTableResponse =
|
2025-01-15 10:33:07 +00:00
|
|
|
"//div[@data-guided-tour-id='query-table-response']//div[@class='tbody']//div[@class ='td as-mask']";
|
2022-06-17 11:31:40 +00:00
|
|
|
_queryResponseHeader = (header: string) =>
|
|
|
|
|
"//div[@data-guided-tour-id='query-table-response']//div[@class='table']//div[@role ='columnheader']//span[text()='" +
|
|
|
|
|
header +
|
|
|
|
|
"']";
|
2022-05-31 05:33:59 +00:00
|
|
|
_refreshIcon = "button .bp3-icon-refresh";
|
|
|
|
|
_addIcon = "button .bp3-icon-add";
|
2024-12-10 07:06:57 +00:00
|
|
|
_queryError = "[data-testid='t--response-error']";
|
2023-05-19 18:37:06 +00:00
|
|
|
_queryEditorTabs = (responseType: string) =>
|
|
|
|
|
"//button[@role='tab' or @role='tablist']//span[text()='" +
|
|
|
|
|
responseType +
|
|
|
|
|
"']";
|
2022-06-06 05:59:15 +00:00
|
|
|
_queryResponse = (responseType: string) =>
|
2023-05-19 18:37:06 +00:00
|
|
|
"//div[@data-testid='t--response-tab-segmented-control']//span[text()='" +
|
|
|
|
|
responseType +
|
|
|
|
|
"']";
|
2024-12-03 03:51:43 +00:00
|
|
|
// TODO: remove this when response UI is ready
|
2022-06-06 05:59:15 +00:00
|
|
|
_queryRecordResult = (recordCount: number) =>
|
2023-07-28 09:18:40 +00:00
|
|
|
`//div/span[text()='Result:']/span[number(substring-before(normalize-space(text()), ' Record')) >= ${recordCount}]`;
|
2022-06-16 06:50:02 +00:00
|
|
|
_noRecordFound = "span[data-testid='no-data-table-message']";
|
2022-06-17 06:12:18 +00:00
|
|
|
_usePreparedStatement =
|
2023-09-19 19:26:11 +00:00
|
|
|
"input[name='actionConfiguration.pluginSpecifiedTemplates[0].value'][type='checkbox'], input[name='actionConfiguration.formData.preparedStatement.data'][type='checkbox']";
|
2022-07-29 08:48:25 +00:00
|
|
|
_mockDB = (dbName: string) =>
|
2025-01-09 10:48:44 +00:00
|
|
|
"//p[text()='" +
|
2022-07-29 08:48:25 +00:00
|
|
|
dbName +
|
|
|
|
|
"']/ancestor::div[contains(@class, 't--mock-datasource')][1]";
|
2023-03-15 05:03:34 +00:00
|
|
|
private _createBlankGraphQL = ".t--createBlankApiGraphqlCard";
|
|
|
|
|
private _graphQLHeaderKey = "input[name='headers[0].key']";
|
|
|
|
|
private _graphQLHeaderValue = "input[name='headers[0].value']";
|
|
|
|
|
_graphqlQueryEditor = ".t--graphql-query-editor";
|
|
|
|
|
_graphqlVariableEditor = ".t--graphql-variable-editor";
|
2022-09-09 15:59:47 +00:00
|
|
|
_graphqlPagination = {
|
2023-05-19 18:37:06 +00:00
|
|
|
_limitVariable: ".t--apiFormPaginationLimitVariable .rc-select-selector",
|
2022-09-09 15:59:47 +00:00
|
|
|
_limitValue: ".t--apiFormPaginationLimitValue .CodeMirror textarea",
|
2023-05-19 18:37:06 +00:00
|
|
|
_offsetVariable: ".t--apiFormPaginationOffsetVariable .rc-select-selector",
|
2022-09-09 15:59:47 +00:00
|
|
|
_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",
|
|
|
|
|
};
|
2022-08-04 04:48:15 +00:00
|
|
|
_queryDoc = ".t--datasource-documentation-link";
|
|
|
|
|
_globalSearchModal = ".t--global-search-modal";
|
2023-08-01 11:12:44 +00:00
|
|
|
_globalSearchInput = ".t--global-search-input";
|
2022-08-04 04:48:15 +00:00
|
|
|
_gsScopeDropdown =
|
2023-07-03 13:06:05 +00:00
|
|
|
"[data-testid^='datasourceStorages.'][data-testid$='.datasourceConfiguration.authentication.scopeString']";
|
2024-10-09 04:27:44 +00:00
|
|
|
_gsScopeOptions = ".ads-v2-radio-group";
|
2023-08-10 13:55:06 +00:00
|
|
|
_queryTimeout = "//input[@name='actionConfiguration.timeoutInMillisecond']";
|
|
|
|
|
_getStructureReq = "/api/v1/datasources/*/structure?ignoreCache=true";
|
2022-12-30 10:23:24 +00:00
|
|
|
_editDatasourceFromActiveTab = (dsName: string) =>
|
2025-01-09 10:48:44 +00:00
|
|
|
".t--plugin-name:contains('" + dsName + "')";
|
2023-09-13 17:03:14 +00:00
|
|
|
_mandatoryMark = "//span[text()='*']";
|
|
|
|
|
_deleteDSHostPort = ".t--delete-field";
|
2024-12-09 12:42:09 +00:00
|
|
|
_dsTabSchema = "[data-testid='t--tab-DATASOURCE_TAB']";
|
2024-11-06 18:50:52 +00:00
|
|
|
private _pageSelectionMenu = "[data-testid='t--page-selection']";
|
2023-12-05 05:50:36 +00:00
|
|
|
|
|
|
|
|
private _pageSelectMenuItem = ".ads-v2-menu__menu-item";
|
|
|
|
|
|
2023-09-08 07:42:48 +00:00
|
|
|
private _suggestedWidget = (widgetType: string, parentClass: string) =>
|
2024-02-13 08:22:04 +00:00
|
|
|
"//div[contains(@data-testid, '" +
|
2023-09-08 07:42:48 +00:00
|
|
|
parentClass +
|
2024-02-13 08:22:04 +00:00
|
|
|
"')]//div[contains(@data-testid, 't--suggested-widget-" +
|
2023-09-08 07:42:48 +00:00
|
|
|
widgetType +
|
|
|
|
|
"')]";
|
2022-12-30 10:23:24 +00:00
|
|
|
|
2023-03-28 20:07:07 +00:00
|
|
|
_noSchemaAvailable = (dbName: string) =>
|
|
|
|
|
"//div[text()='" +
|
|
|
|
|
dbName +
|
|
|
|
|
"']/ancestor::div[contains(@class, 't--entity-item')]/following-sibling::div//p[text()='Schema not available']";
|
2022-12-30 10:23:24 +00:00
|
|
|
// Authenticated API locators
|
2023-07-29 00:42:08 +00:00
|
|
|
public _authApiDatasource = ".t--createAuthApiDatasource";
|
2023-05-19 18:37:06 +00:00
|
|
|
private _authType = "[data-testid=authType]";
|
|
|
|
|
private _oauth2 = ".rc-select-item-option:contains('OAuth 2.0')";
|
|
|
|
|
private _accessTokenUrl =
|
|
|
|
|
"[data-testid='authentication.accessTokenUrl'] input";
|
|
|
|
|
private _clientID = "[data-testid='authentication.clientId'] input";
|
|
|
|
|
private _clientSecret = "[data-testid='authentication.clientSecret'] input";
|
2023-03-10 11:39:06 +00:00
|
|
|
private _clientCredentails =
|
2023-05-19 18:37:06 +00:00
|
|
|
".rc-select-item-option:contains('Client Credentials')";
|
2022-12-30 10:23:24 +00:00
|
|
|
private _authorizationCode =
|
2023-05-19 18:37:06 +00:00
|
|
|
".rc-select-item-option:contains('Authorization Code')";
|
|
|
|
|
private _grantType = "[data-testid='authentication.grantType']";
|
2022-12-30 10:23:24 +00:00
|
|
|
private _authorizationURL =
|
2023-05-19 18:37:06 +00:00
|
|
|
"[data-testid='authentication.authorizationUrl'] input";
|
2023-08-03 07:12:30 +00:00
|
|
|
_consent = '[name="confirm"]';
|
|
|
|
|
_consentSubmit = "//button[text()='Submit']";
|
2022-12-13 11:46:56 +00:00
|
|
|
public _datasourceModalSave = ".t--datasource-modal-save";
|
|
|
|
|
public _datasourceModalDoNotSave = ".t--datasource-modal-do-not-save";
|
2023-05-22 12:05:59 +00:00
|
|
|
public _cancelEditDatasourceButton = ".t--cancel-edit-datasource";
|
2023-03-16 18:28:32 +00:00
|
|
|
public _urlInputControl = "input[name='url']";
|
2023-08-25 10:41:45 +00:00
|
|
|
public _headerKey = "input[name='headers[0].key']";
|
2023-06-14 06:46:09 +00:00
|
|
|
public _mongoCollectionPath = "t--actionConfiguration.formData.collection";
|
2023-07-26 13:26:24 +00:00
|
|
|
_getJSONswitchLocator = (fieldName: string) =>
|
|
|
|
|
"//p[contains(text(),'" +
|
|
|
|
|
fieldName +
|
|
|
|
|
"')]/ancestor::div[@class='form-config-top']//button";
|
2023-04-04 15:56:57 +00:00
|
|
|
_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) =>
|
2023-05-19 18:37:06 +00:00
|
|
|
"[data-testid='t--where-clause-delete-[" + index + "]']";
|
2022-05-31 05:33:59 +00:00
|
|
|
|
2023-04-06 04:07:04 +00:00
|
|
|
_bodyCodeMirror = "//div[contains(@class, 't--actionConfiguration.body')]";
|
2023-06-21 17:37:21 +00:00
|
|
|
private _reconnectModalDSToolTip = ".t--ds-list .t--ds-list-title";
|
|
|
|
|
private _reconnectModalDSToopTipIcon = ".t--ds-list .ads-v2-icon";
|
2023-07-26 13:26:24 +00:00
|
|
|
_multiSelectDropdown = (ddName: string) =>
|
|
|
|
|
"//p[contains(text(),'" +
|
|
|
|
|
ddName +
|
|
|
|
|
"')]/ancestor::div[@class='form-config-top']/following-sibling::div//div[contains(@class, 'rc-select-multiple')]";
|
2023-07-24 12:09:46 +00:00
|
|
|
private _datasourceSchemaRefreshBtn = ".datasourceStructure-refresh";
|
2023-07-24 06:48:20 +00:00
|
|
|
private _datasourceStructureHeader = ".datasourceStructure-header";
|
feat: Schema tab UI update (#37420)
## Description
Updated schema tab as per new design.
https://www.figma.com/design/8L9BXMzNTKboGWlHpdXyYP/Appsmith-IDE?node-id=3071-101845&node-type=text&m=dev
Fixes #35289
## Automation
/ok-to-test tags="@tag.Sanity"
### :mag: Cypress test results
<!-- This is an auto-generated comment: Cypress test results -->
> [!TIP]
> 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉
> Workflow run:
<https://github.com/appsmithorg/appsmith/actions/runs/12022221992>
> Commit: c38fc9948554344a45c172fe291f49a0a5cd9b61
> <a
href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=12022221992&attempt=2"
target="_blank">Cypress dashboard</a>.
> Tags: `@tag.Sanity`
> Spec:
> <hr>Tue, 26 Nov 2024 03:45:12 UTC
<!-- end of auto-generated comment: Cypress test results -->
## Communication
Should the DevRel and Marketing teams inform users about this change?
- [ ] Yes
- [x] No
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
## Release Notes
- **New Features**
- Introduced new components: `CurrentDataSource`, `DatasourceSelector`,
`SchemaTables`, `TableColumns`, `StatusDisplay`,
`CurrentDataSourceLink`, `Schema`, `MenuField`, and custom hooks
`useCreateDatasource` and `useGoToDatasource`.
- Added constants for improved user feedback in schema-related messages.
- **Improvements**
- Enhanced layout and styling for various components, including
`BottomView` and `Schema`.
- Updated test identifiers for better consistency and testability.
- **Bug Fixes**
- Adjusted test cases to ensure accurate schema validation.
- **Refactor**
- Updated internal logic for handling datasource interactions and state
management across components.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2024-11-26 04:12:33 +00:00
|
|
|
_datasourceSchemaColumn = ".t--datasource-column .t--field-name";
|
2023-10-06 12:05:19 +00:00
|
|
|
_datasourceStructureSearchInput = ".datasourceStructure-search input";
|
2023-07-26 13:26:24 +00:00
|
|
|
_jsModeSortingControl = ".t--actionConfiguration\\.formData\\.sortBy\\.data";
|
2023-07-24 12:09:46 +00:00
|
|
|
public _queryEditorCollapsibleIcon = ".collapsible-icon";
|
2023-08-01 11:12:44 +00:00
|
|
|
_globalSearchTrigger = ".t--global-search-modal-trigger";
|
|
|
|
|
_globalSearchOptions = ".t--searchHit";
|
2023-08-08 09:14:46 +00:00
|
|
|
private _dataSourceInfo = (dsName: string) =>
|
|
|
|
|
"//span[text()='" +
|
|
|
|
|
dsName +
|
|
|
|
|
"']/ancestor::div[contains(@class, 't--datasource')]//div[@data-testid='datasource-collapse-wrapper']";
|
2023-08-18 05:18:35 +00:00
|
|
|
_snippingBanner = ".t--sniping-mode-banner";
|
2023-08-21 07:49:28 +00:00
|
|
|
_s3CrudIcons = (
|
|
|
|
|
fieldName: string,
|
|
|
|
|
type: "Edit" | "Delete" | "CopyURL" | "Download",
|
|
|
|
|
) =>
|
|
|
|
|
"//span[text()='" +
|
|
|
|
|
fieldName +
|
|
|
|
|
"']/ancestor::div[@type='CANVAS_WIDGET'][1]//div[@data-widgetname-cy='" +
|
|
|
|
|
type +
|
|
|
|
|
"Icon']";
|
|
|
|
|
_s3EditFileName =
|
|
|
|
|
"[data-widgetname-cy='update_file_name'] div[data-testid='input-container']";
|
|
|
|
|
_s3MaxFileSizeAlert = "//p[@role='alert']";
|
fix: entity explorer issue with datasources is fixed (#26770)
## Description
This PR fixes issue with datasource not getting highlighted in entity
explorer:
Suppose we have 3 datasources in our applications: Users, Movies, and
one Postgres or MySQL datasource. Once we create these datasources, we
can see them getting populated in entity explorer -> datasource section.
So there were two issues here:
- If I select Users, I am able to see the Users datasource info on the
right pane but its not active in the entity explorer, Similarly If I
switch to movies, right pane gets updated with movies info but in the
entity explorer, we cannot see movies getting highlighted as thats the
active selection
- If I am on Users datasource review page, I reload the page, now I can
see active selection of Users being highlighted in the entity explorer,
but now if we switch to Movies, right pane gets updated but in entity
explorer Users is highlighted, which is incorrect
This issue occurred because we have used useMemo for
`datasourceElements`, two dependency passed are appWideDS and pageId,
whenever we switch between datasources, `activeDatasourceId` gets
updated but since we have cached the whole datasource listing component
without the dependency of `activeDatasourceId`, it does not recompute
and shows the same state as before.
To fix the issue, `activeDatasourceId` needs to be passed in the
dependency array. After adding this new dependency, another issue
occurred with respect to entity explorer, The order of suggested
datasources would change in entity explorer, This PR addresses that
issue as well.
#### PR fixes following issue(s)
Fixes #26716
> 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
- Bug fix (non-breaking change which fixes an issue)
>
>
>
## 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
- [ ] JUnit
- [x] Jest
- [ ] Cypress
>
>
#### Test Plan
> Add Testsmith test cases links that relate to this PR
>
>
#### Issues raised during DP testing
> Link issues raised during DP testing for better visiblity 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:
- [x] [Speedbreak
features](https://github.com/appsmithorg/TestSmith/wiki/Guidelines-for-test-plans#speedbreakers-)
have been covered
- [ ] Test plan covers all impacted features and [areas of
interest](https://github.com/appsmithorg/TestSmith/wiki/Guidelines-for-test-plans#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
- [ ] Cypress test cases have been added and approved by SDET/manual QA
- [ ] 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”>
2023-09-01 07:56:34 +00:00
|
|
|
_entityExplorerID = (dsName: string) =>
|
|
|
|
|
"[data-testid='t--entity-item-" + dsName + "']";
|
2023-09-04 13:30:21 +00:00
|
|
|
_stagingTab = "[data-testid='t--ds-data-filter-Staging']";
|
2024-02-15 06:21:25 +00:00
|
|
|
_graphQlDsHintOption = (dsName: string) =>
|
2023-09-04 13:30:21 +00:00
|
|
|
"//div/span[text() ='" + dsName + "']";
|
2023-09-27 17:24:27 +00:00
|
|
|
_imgFireStoreLogo = "//img[contains(@src, 'firestore.svg')]";
|
2023-11-15 02:31:12 +00:00
|
|
|
_dsVirtuosoElement = `div .t--schema-virtuoso-container`;
|
2023-09-26 07:34:41 +00:00
|
|
|
private _dsVirtuosoList = `[data-test-id="virtuoso-item-list"]`;
|
feat: Schema tab UI update (#37420)
## Description
Updated schema tab as per new design.
https://www.figma.com/design/8L9BXMzNTKboGWlHpdXyYP/Appsmith-IDE?node-id=3071-101845&node-type=text&m=dev
Fixes #35289
## Automation
/ok-to-test tags="@tag.Sanity"
### :mag: Cypress test results
<!-- This is an auto-generated comment: Cypress test results -->
> [!TIP]
> 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉
> Workflow run:
<https://github.com/appsmithorg/appsmith/actions/runs/12022221992>
> Commit: c38fc9948554344a45c172fe291f49a0a5cd9b61
> <a
href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=12022221992&attempt=2"
target="_blank">Cypress dashboard</a>.
> Tags: `@tag.Sanity`
> Spec:
> <hr>Tue, 26 Nov 2024 03:45:12 UTC
<!-- end of auto-generated comment: Cypress test results -->
## Communication
Should the DevRel and Marketing teams inform users about this change?
- [ ] Yes
- [x] No
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
## Release Notes
- **New Features**
- Introduced new components: `CurrentDataSource`, `DatasourceSelector`,
`SchemaTables`, `TableColumns`, `StatusDisplay`,
`CurrentDataSourceLink`, `Schema`, `MenuField`, and custom hooks
`useCreateDatasource` and `useGoToDatasource`.
- Added constants for improved user feedback in schema-related messages.
- **Improvements**
- Enhanced layout and styling for various components, including
`BottomView` and `Schema`.
- Updated test identifiers for better consistency and testability.
- **Bug Fixes**
- Adjusted test cases to ensure accurate schema validation.
- **Refactor**
- Updated internal logic for handling datasource interactions and state
management across components.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2024-11-26 04:12:33 +00:00
|
|
|
private _dsSchemaContainer = `[data-testid="t--datasource-schema-container"]`;
|
2023-09-26 07:34:41 +00:00
|
|
|
private _dsVirtuosoElementTable = (targetTableName: string) =>
|
2024-02-02 09:56:26 +00:00
|
|
|
`${this._dsSchemaEntityItem}[data-testid='t--entity-item-${targetTableName}']`;
|
2023-10-06 12:05:19 +00:00
|
|
|
private _dsPageTabListItem = (buttonText: string) =>
|
|
|
|
|
`//div[contains(@class, 't--datasource-tab-list')]/button/span[text()='${buttonText}']`;
|
|
|
|
|
_dsPageTabContainerTableName = (tableName: string) =>
|
|
|
|
|
`.t--datasource-tab-container ${this._entityExplorerID(tableName)}`;
|
|
|
|
|
_dsPageTableTriggermenuTarget = (tableName: string) =>
|
2024-02-02 09:56:26 +00:00
|
|
|
`${this._dsPageTabContainerTableName(tableName)} ${
|
|
|
|
|
this._entityTriggerElement
|
|
|
|
|
}`;
|
2023-10-11 07:34:47 +00:00
|
|
|
_gSheetQueryPlaceholder = ".CodeMirror-placeholder";
|
2023-11-13 07:08:04 +00:00
|
|
|
_dsStructurePreviewMode = ".datasourceStructure-datasource-view-mode";
|
2024-02-02 09:56:26 +00:00
|
|
|
private _dsSchemaEntityItem = ".t--entity-item";
|
|
|
|
|
private _entityTriggerElement = ".t--template-menu-trigger";
|
2024-02-13 11:49:13 +00:00
|
|
|
_dsSchemaTableResponse = ".t--table-response";
|
test: Add cypress tests for Snowflake datasource functionalities (#39029)
## Description
This PR introduces cypress tests to ensure the functionality &
reliability of the Snowflake datasource integration.
## Automation
/ok-to-test tags="@tag.Datasource, @tag.Git, @tag.Sanity"
### :mag: Cypress test results
<!-- This is an auto-generated comment: Cypress test results -->
> [!TIP]
> 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉
> Workflow run:
<https://github.com/appsmithorg/appsmith/actions/runs/13192562126>
> Commit: 3adb00b2d4fbc211fe2ad6a347cf6b9bcca2ac56
> <a
href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=13192562126&attempt=1"
target="_blank">Cypress dashboard</a>.
> Tags: `@tag.Datasource, @tag.Git, @tag.Sanity`
> Spec:
> <hr>Fri, 07 Feb 2025 05:31:43 UTC
<!-- end of auto-generated comment: Cypress test results -->
## Communication
Should the DevRel and Marketing teams inform users about this change?
- [ ] Yes
- [x] No
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
## Summary by CodeRabbit
- **New Features**
- Introduced streamlined support for Snowflake datasource integration,
enabling users to easily enter Snowflake connection details and
configuration settings directly within the application.
- Added a new method for filling out Snowflake datasource forms,
enhancing user experience in configuring Snowflake settings.
- Expanded the list of available tags within the application to include
Snowflake.
- **Tests**
- Rolled out comprehensive end-to-end tests that validate configuration,
query execution, widget integration, deployment outcomes, deletion
workflows, and error handling to ensure a robust experience with
Snowflake integration.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-02-07 05:33:18 +00:00
|
|
|
_imgSnowflakeLogo = "//img[contains(@src, 'snowflake.svg')]";
|
|
|
|
|
_dsConfigProperties = (index: number) =>
|
|
|
|
|
"input[name*='datasourceConfiguration.properties[" + index + "]']";
|
|
|
|
|
_dsConfigAuthType = `[data-testid*='datasourceConfiguration.authentication.authenticationType']`;
|
2023-04-06 04:07:04 +00:00
|
|
|
|
2023-11-03 06:57:24 +00:00
|
|
|
public AssertDSEditViewMode(mode: AppModes) {
|
2023-03-16 18:28:32 +00:00
|
|
|
if (mode == "Edit") this.agHelper.AssertElementAbsence(this._editButton);
|
|
|
|
|
else if (mode == "View") this.agHelper.AssertElementExist(this._editButton);
|
2022-12-02 03:06:22 +00:00
|
|
|
}
|
|
|
|
|
|
2023-05-11 18:45:06 +00:00
|
|
|
public GeneratePageWithDB(datasourceName: any, tableName: string) {
|
2023-11-29 11:11:33 +00:00
|
|
|
PageList.AddNewPage("Generate page with data");
|
2023-05-11 18:45:06 +00:00
|
|
|
this.agHelper.GetNClick(this._selectDatasourceDropdown);
|
|
|
|
|
this.agHelper.GetNClickByContains(
|
|
|
|
|
this.locator._dropdownText,
|
|
|
|
|
datasourceName,
|
|
|
|
|
);
|
2023-05-19 18:37:06 +00:00
|
|
|
this.agHelper.GetNClick(this._selectTableDropdown, 0, true);
|
2024-10-22 12:14:54 +00:00
|
|
|
cy.get(`div[role="listbox"] p:contains("${tableName}")`).click();
|
2023-05-11 18:45:06 +00:00
|
|
|
this.agHelper.GetNClick(this._generatePageBtn);
|
2023-06-18 04:55:16 +00:00
|
|
|
this.assertHelper.AssertNetworkStatus("@replaceLayoutWithCRUDPage", 201);
|
2023-08-30 10:54:37 +00:00
|
|
|
this.agHelper.ClickButton("Got it");
|
2023-05-11 18:45:06 +00:00
|
|
|
}
|
|
|
|
|
|
2023-01-09 14:51:13 +00:00
|
|
|
public GeneratePageWithMockDB() {
|
2023-11-29 11:11:33 +00:00
|
|
|
PageList.AddNewPage("Generate page with data");
|
2023-01-09 14:51:13 +00:00
|
|
|
this.agHelper.GetNClick(this._selectDatasourceDropdown);
|
2023-06-15 13:21:11 +00:00
|
|
|
this.agHelper.GetNClickByContains(
|
|
|
|
|
this._dropdownOption,
|
|
|
|
|
"Connect new datasource",
|
|
|
|
|
);
|
|
|
|
|
this.agHelper.GetNClick(this._mockDB("Users"));
|
|
|
|
|
this.agHelper.Sleep(500);
|
2023-06-18 04:55:16 +00:00
|
|
|
this.assertHelper.AssertNetworkStatus("@getDatasourceStructure"); //Making sure table dropdown is populated
|
2023-05-19 18:37:06 +00:00
|
|
|
this.agHelper.GetNClick(this._selectTableDropdown, 0, true);
|
2023-06-15 13:21:11 +00:00
|
|
|
this.agHelper.GetNClickByContains(this._dropdownOption, "public.users");
|
2023-10-25 14:03:07 +00:00
|
|
|
this.agHelper.GetNClick(this._generatePageBtn, 0, true);
|
2023-06-18 04:55:16 +00:00
|
|
|
this.assertHelper.AssertNetworkStatus("@replaceLayoutWithCRUDPage", 201);
|
2023-08-30 10:54:37 +00:00
|
|
|
this.agHelper.ClickButton("Got it");
|
2023-01-09 14:51:13 +00:00
|
|
|
}
|
|
|
|
|
|
2022-05-31 05:33:59 +00:00
|
|
|
public StartDataSourceRoutes() {
|
2022-11-30 05:59:45 +00:00
|
|
|
cy.intercept("POST", "/api/v1/datasources").as("saveDatasource");
|
2022-05-31 05:33:59 +00:00
|
|
|
cy.intercept("POST", "/api/v1/datasources/test").as("testDatasource");
|
2022-11-30 05:59:45 +00:00
|
|
|
cy.intercept("PUT", "/api/v1/datasources/*").as("updateDatasource");
|
2022-05-31 05:33:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
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");
|
|
|
|
|
}
|
2022-05-18 10:39:42 +00:00
|
|
|
|
2022-06-06 05:59:15 +00:00
|
|
|
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");
|
|
|
|
|
}
|
|
|
|
|
|
2022-08-04 04:48:15 +00:00
|
|
|
public StartInterceptRoutesForFirestore() {
|
|
|
|
|
//All stubbing
|
|
|
|
|
cy.intercept("POST", "/api/v1/datasources/test", {
|
|
|
|
|
fixture: "testAction.json",
|
|
|
|
|
}).as("testDatasource");
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-30 07:22:10 +00:00
|
|
|
public CreatePlugIn(
|
|
|
|
|
pluginName: string,
|
|
|
|
|
waitForToastDisappear = false,
|
|
|
|
|
index = 0,
|
|
|
|
|
) {
|
2022-05-31 05:33:59 +00:00
|
|
|
cy.get(this._createNewPlgin(pluginName))
|
|
|
|
|
.parent("div")
|
2024-01-30 07:22:10 +00:00
|
|
|
.eq(index)
|
2022-05-31 05:33:59 +00:00
|
|
|
.trigger("click", { force: true });
|
2022-11-30 05:59:45 +00:00
|
|
|
this.agHelper.Sleep();
|
|
|
|
|
//this.agHelper.WaitUntilEleAppear(this.locator._toastMsg);
|
2022-09-07 18:25:55 +00:00
|
|
|
this.agHelper.AssertElementAbsence(
|
|
|
|
|
this.locator._specificToast("Duplicate key error"),
|
|
|
|
|
);
|
2022-12-09 05:06:52 +00:00
|
|
|
this.agHelper.PressEscape();
|
2022-11-30 05:59:45 +00:00
|
|
|
// if (waitForToastDisappear)
|
|
|
|
|
// this.agHelper.WaitUntilToastDisappear("datasource created");
|
|
|
|
|
// else this.agHelper.AssertContains("datasource created");
|
2022-05-18 10:39:42 +00:00
|
|
|
}
|
|
|
|
|
|
2022-12-02 03:06:22 +00:00
|
|
|
public EditDatasource() {
|
|
|
|
|
this.agHelper.GetNClick(this._editButton);
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-18 10:39:42 +00:00
|
|
|
public NavigateToDSCreateNew() {
|
2023-11-28 11:11:54 +00:00
|
|
|
AppSidebar.navigate(AppSidebarButton.Data);
|
2024-01-05 06:12:03 +00:00
|
|
|
cy.get("body").then(($body) => {
|
|
|
|
|
if ($body.find(this._addNewDataSource).length > 0) {
|
|
|
|
|
this.agHelper.GetNClick(this._addNewDataSource, 0, true);
|
|
|
|
|
} else {
|
|
|
|
|
this.agHelper.GetNClick(this._addNewDatasourceFromBlankScreen, 0, true);
|
|
|
|
|
}
|
2023-05-19 18:37:06 +00:00
|
|
|
});
|
2024-01-05 06:12:03 +00:00
|
|
|
this.agHelper.AssertElementVisibility(this._newDatabases);
|
2022-05-18 10:39:42 +00:00
|
|
|
}
|
|
|
|
|
|
2022-10-20 12:08:48 +00:00
|
|
|
CreateMockDB(dbName: "Users" | "Movies"): Cypress.Chainable<string> {
|
|
|
|
|
this.NavigateToDSCreateNew();
|
2023-11-15 02:31:12 +00:00
|
|
|
cy.get(this._mockDatasourceName)
|
|
|
|
|
.contains(dbName, { matchCase: false })
|
|
|
|
|
.click();
|
2023-06-17 08:23:03 +00:00
|
|
|
this.assertHelper.AssertNetworkStatus("@getMockDb"); //To return the right mock DB name
|
2022-10-20 12:08:48 +00:00
|
|
|
return cy
|
2023-06-17 08:23:03 +00:00
|
|
|
.get("@getMockDb")
|
|
|
|
|
.then(($createdMock: any) => $createdMock.response?.body.data.name);
|
2022-10-20 12:08:48 +00:00
|
|
|
}
|
|
|
|
|
|
2022-07-20 18:01:50 +00:00
|
|
|
public FillPostgresDSForm(
|
2023-08-18 05:18:35 +00:00
|
|
|
environment = this.dataManager.defaultEnviorment,
|
2022-07-20 18:01:50 +00:00
|
|
|
shouldAddTrailingSpaces = false,
|
|
|
|
|
username = "",
|
|
|
|
|
password = "",
|
|
|
|
|
) {
|
2022-05-18 10:39:42 +00:00
|
|
|
const hostAddress = shouldAddTrailingSpaces
|
2023-08-18 05:18:35 +00:00
|
|
|
? this.dataManager.dsValues[environment].postgres_host + " "
|
|
|
|
|
: this.dataManager.dsValues[environment].postgres_host;
|
2022-05-18 10:39:42 +00:00
|
|
|
const databaseName = shouldAddTrailingSpaces
|
2023-08-18 05:18:35 +00:00
|
|
|
? this.dataManager.dsValues[environment].postgres_databaseName + " "
|
|
|
|
|
: this.dataManager.dsValues[environment].postgres_databaseName;
|
fix: connection mode hidden from mysql form config (#32487)
## Description
MySQL datasource config has a field called `Connection mode`, which
allows users to configure their datasource either in read write / read
only mode. This is supposed to block the write queries if datasource is
configured with read only mode, but with current implementation, it does
not block, it lets us execute write query.
On checking the codebase, it seems that this field is not at all being
used in mySQL plugin to configure the datasource, further more mysql
driver used may not even support configuring connection mode as of now,
hence as preventive solution, hiding the connection mode form config for
now.
Fixes https://github.com/appsmithorg/appsmith/issues/9941
> [!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="@tag.Datasource"
### :mag: Cypress test results
<!-- This is an auto-generated comment: Cypress test results -->
> [!IMPORTANT]
> Workflow run:
<https://github.com/appsmithorg/appsmith/actions/runs/8612888064>
> Commit: `0a0d20e1fb40546e635ba018704b5f13ecc97ab1`
> Cypress dashboard url: <a
href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=8612888064&attempt=1"
target="_blank">Click here!</a>
> All cypress tests have passed 🎉🎉🎉
<!-- end of auto-generated comment: Cypress test results -->
---------
Co-authored-by: “sneha122” <“sneha@appsmith.com”>
2024-04-10 07:04:04 +00:00
|
|
|
this.ValidateNSelectDropdown("Connection mode", "Read / Write");
|
2024-04-30 07:45:11 +00:00
|
|
|
this.agHelper.ClearNType(
|
2023-05-19 18:37:06 +00:00
|
|
|
this._port,
|
2023-08-18 05:18:35 +00:00
|
|
|
this.dataManager.dsValues[environment].postgres_port.toString(),
|
2023-05-19 18:37:06 +00:00
|
|
|
);
|
2024-04-30 07:45:11 +00:00
|
|
|
this.agHelper.ClearNType(this._host(), hostAddress);
|
2023-08-08 09:14:46 +00:00
|
|
|
this.agHelper.ClearNType(this._databaseName, databaseName);
|
2024-04-30 07:45:11 +00:00
|
|
|
|
|
|
|
|
this.agHelper.ClearNType(
|
|
|
|
|
this._username,
|
2023-07-21 05:53:17 +00:00
|
|
|
username == ""
|
2023-08-18 05:18:35 +00:00
|
|
|
? this.dataManager.dsValues[environment].postgres_username
|
2023-07-21 05:53:17 +00:00
|
|
|
: username,
|
2022-07-20 18:01:50 +00:00
|
|
|
);
|
2024-04-30 07:45:11 +00:00
|
|
|
|
|
|
|
|
this.agHelper.ClearNType(
|
|
|
|
|
this._password,
|
2023-07-21 05:53:17 +00:00
|
|
|
password == ""
|
2023-08-18 05:18:35 +00:00
|
|
|
? this.dataManager.dsValues[environment].postgres_password
|
2023-07-21 05:53:17 +00:00
|
|
|
: password,
|
2022-07-20 18:01:50 +00:00
|
|
|
);
|
2023-06-21 17:37:21 +00:00
|
|
|
this.ValidateNSelectDropdown("SSL mode", "Default");
|
2022-05-18 10:39:42 +00:00
|
|
|
}
|
|
|
|
|
|
2023-07-26 18:13:54 +00:00
|
|
|
public ValidatePostgresDSForm(
|
2023-08-18 05:18:35 +00:00
|
|
|
environment = this.dataManager.defaultEnviorment,
|
2023-07-26 18:13:54 +00:00
|
|
|
) {
|
|
|
|
|
const databaseName =
|
2023-08-18 05:18:35 +00:00
|
|
|
this.dataManager.dsValues[environment].postgres_databaseName;
|
2023-07-26 18:13:54 +00:00
|
|
|
this.agHelper.AssertContains(databaseName, "exist", this._dsReviewSection);
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-18 05:18:35 +00:00
|
|
|
public ValidateMongoForm(environment = this.dataManager.defaultEnviorment) {
|
2023-07-26 18:13:54 +00:00
|
|
|
const databaseName =
|
2023-08-18 05:18:35 +00:00
|
|
|
this.dataManager.dsValues[environment].mongo_databaseName;
|
2023-07-26 18:13:54 +00:00
|
|
|
this.agHelper.AssertContains(this._dsReviewSection, databaseName);
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-12 17:48:46 +00:00
|
|
|
public FillOracleDSForm(
|
2023-08-18 05:18:35 +00:00
|
|
|
environment = this.dataManager.defaultEnviorment,
|
2023-06-12 17:48:46 +00:00
|
|
|
shouldAddTrailingSpaces = false,
|
|
|
|
|
username = "",
|
|
|
|
|
password = "",
|
|
|
|
|
) {
|
|
|
|
|
const hostAddress = shouldAddTrailingSpaces
|
2023-08-18 05:18:35 +00:00
|
|
|
? this.dataManager.dsValues[environment].oracle_host + " "
|
|
|
|
|
: this.dataManager.dsValues[environment].oracle_host;
|
2023-06-12 17:48:46 +00:00
|
|
|
const databaseName = shouldAddTrailingSpaces
|
2023-09-13 17:03:14 +00:00
|
|
|
? this.dataManager.dsValues[environment].oracle_service + " "
|
|
|
|
|
: this.dataManager.dsValues[environment].oracle_service;
|
2024-04-30 07:45:11 +00:00
|
|
|
this.agHelper.ClearNType(this._host(), hostAddress);
|
|
|
|
|
this.agHelper.ClearNType(
|
2023-07-11 05:14:13 +00:00
|
|
|
this._port,
|
2023-08-18 05:18:35 +00:00
|
|
|
this.dataManager.dsValues[environment].oracle_port.toString(),
|
2023-07-11 05:14:13 +00:00
|
|
|
);
|
2024-04-30 07:45:11 +00:00
|
|
|
this.agHelper.ClearNType(this._databaseName, databaseName);
|
|
|
|
|
this.agHelper.ClearNType(
|
|
|
|
|
this._username,
|
2023-07-21 05:53:17 +00:00
|
|
|
username == ""
|
2023-08-18 05:18:35 +00:00
|
|
|
? this.dataManager.dsValues[environment].oracle_username
|
2023-07-21 05:53:17 +00:00
|
|
|
: username,
|
2023-06-12 17:48:46 +00:00
|
|
|
);
|
2024-04-30 07:45:11 +00:00
|
|
|
this.agHelper.ClearNType(
|
|
|
|
|
this._password,
|
2023-07-21 05:53:17 +00:00
|
|
|
password == ""
|
2023-08-18 05:18:35 +00:00
|
|
|
? this.dataManager.dsValues[environment].oracle_password
|
2023-07-21 05:53:17 +00:00
|
|
|
: password,
|
2023-06-12 17:48:46 +00:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
test: Add cypress tests for Snowflake datasource functionalities (#39029)
## Description
This PR introduces cypress tests to ensure the functionality &
reliability of the Snowflake datasource integration.
## Automation
/ok-to-test tags="@tag.Datasource, @tag.Git, @tag.Sanity"
### :mag: Cypress test results
<!-- This is an auto-generated comment: Cypress test results -->
> [!TIP]
> 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉
> Workflow run:
<https://github.com/appsmithorg/appsmith/actions/runs/13192562126>
> Commit: 3adb00b2d4fbc211fe2ad6a347cf6b9bcca2ac56
> <a
href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=13192562126&attempt=1"
target="_blank">Cypress dashboard</a>.
> Tags: `@tag.Datasource, @tag.Git, @tag.Sanity`
> Spec:
> <hr>Fri, 07 Feb 2025 05:31:43 UTC
<!-- end of auto-generated comment: Cypress test results -->
## Communication
Should the DevRel and Marketing teams inform users about this change?
- [ ] Yes
- [x] No
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
## Summary by CodeRabbit
- **New Features**
- Introduced streamlined support for Snowflake datasource integration,
enabling users to easily enter Snowflake connection details and
configuration settings directly within the application.
- Added a new method for filling out Snowflake datasource forms,
enhancing user experience in configuring Snowflake settings.
- Expanded the list of available tags within the application to include
Snowflake.
- **Tests**
- Rolled out comprehensive end-to-end tests that validate configuration,
query execution, widget integration, deployment outcomes, deletion
workflows, and error handling to ensure a robust experience with
Snowflake integration.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-02-07 05:33:18 +00:00
|
|
|
public FillSnowflakeDSForm(
|
|
|
|
|
environment = this.dataManager.defaultEnviorment,
|
|
|
|
|
username = "",
|
|
|
|
|
password = "",
|
|
|
|
|
) {
|
|
|
|
|
const accountName =
|
|
|
|
|
this.dataManager.dsValues[environment].Snowflake_accountName;
|
|
|
|
|
const warehouseName =
|
|
|
|
|
this.dataManager.dsValues[environment].Snowflake_warehouseName;
|
|
|
|
|
const databaseName =
|
|
|
|
|
this.dataManager.dsValues[environment].Snowflake_databaseName;
|
|
|
|
|
const schemaName =
|
|
|
|
|
this.dataManager.dsValues[environment].Snowflake_defaultSchema;
|
|
|
|
|
const role = this.dataManager.dsValues[environment].Snowflake_role;
|
|
|
|
|
this.agHelper.ClearNType(datasource.datasourceConfigUrl, accountName);
|
|
|
|
|
this.agHelper.ClearNType(this._dsConfigProperties(0), warehouseName);
|
|
|
|
|
this.agHelper.ClearNType(this._dsConfigProperties(1), databaseName);
|
|
|
|
|
this.agHelper.ClearNType(this._dsConfigProperties(2), schemaName);
|
|
|
|
|
this.agHelper.ClearNType(this._dsConfigProperties(3), role);
|
|
|
|
|
this.agHelper.AssertContains("Basic", "exist", this._dsConfigAuthType)
|
|
|
|
|
? null
|
|
|
|
|
: this.agHelper.GetNClick(this._dsConfigAuthType) &&
|
|
|
|
|
this.agHelper.ContainsNClick("Basic");
|
|
|
|
|
this.agHelper.ClearNType(
|
|
|
|
|
this._username,
|
|
|
|
|
username == ""
|
|
|
|
|
? this.dataManager.dsValues[environment].Snowflake_username
|
|
|
|
|
: username,
|
|
|
|
|
);
|
|
|
|
|
this.agHelper.ClearNType(
|
|
|
|
|
this._password,
|
|
|
|
|
password == ""
|
|
|
|
|
? this.dataManager.dsValues[environment].Snowflake_password
|
|
|
|
|
: password,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-21 05:53:17 +00:00
|
|
|
public FillMongoDSForm(
|
2023-08-18 05:18:35 +00:00
|
|
|
environment = this.dataManager.defaultEnviorment,
|
2023-07-21 05:53:17 +00:00
|
|
|
shouldAddTrailingSpaces = false,
|
|
|
|
|
) {
|
2022-05-23 05:20:27 +00:00
|
|
|
const hostAddress = shouldAddTrailingSpaces
|
2023-08-18 05:18:35 +00:00
|
|
|
? this.dataManager.dsValues[environment].mongo_host + " "
|
|
|
|
|
: this.dataManager.dsValues[environment].mongo_host;
|
fix: connection mode hidden from mysql form config (#32487)
## Description
MySQL datasource config has a field called `Connection mode`, which
allows users to configure their datasource either in read write / read
only mode. This is supposed to block the write queries if datasource is
configured with read only mode, but with current implementation, it does
not block, it lets us execute write query.
On checking the codebase, it seems that this field is not at all being
used in mySQL plugin to configure the datasource, further more mysql
driver used may not even support configuring connection mode as of now,
hence as preventive solution, hiding the connection mode form config for
now.
Fixes https://github.com/appsmithorg/appsmith/issues/9941
> [!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="@tag.Datasource"
### :mag: Cypress test results
<!-- This is an auto-generated comment: Cypress test results -->
> [!IMPORTANT]
> Workflow run:
<https://github.com/appsmithorg/appsmith/actions/runs/8612888064>
> Commit: `0a0d20e1fb40546e635ba018704b5f13ecc97ab1`
> Cypress dashboard url: <a
href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=8612888064&attempt=1"
target="_blank">Click here!</a>
> All cypress tests have passed 🎉🎉🎉
<!-- end of auto-generated comment: Cypress test results -->
---------
Co-authored-by: “sneha122” <“sneha@appsmith.com”>
2024-04-10 07:04:04 +00:00
|
|
|
this.ValidateNSelectDropdown("Connection mode", "Read / Write");
|
2024-04-30 07:45:11 +00:00
|
|
|
this.agHelper.ClearNType(this._host(), hostAddress);
|
|
|
|
|
this.agHelper.ClearNType(
|
2023-07-11 05:14:13 +00:00
|
|
|
this._port,
|
2023-08-18 05:18:35 +00:00
|
|
|
this.dataManager.dsValues[environment].mongo_port.toString(),
|
2023-07-11 05:14:13 +00:00
|
|
|
);
|
2023-09-08 09:12:27 +00:00
|
|
|
this.agHelper.ClearTextField(this._databaseName);
|
|
|
|
|
const databaseName = shouldAddTrailingSpaces
|
|
|
|
|
? this.dataManager.dsValues[environment].mongo_databaseName + " "
|
|
|
|
|
: this.dataManager.dsValues[environment].mongo_databaseName;
|
|
|
|
|
this.agHelper.TypeText(this._databaseName, databaseName);
|
2022-05-23 05:20:27 +00:00
|
|
|
}
|
|
|
|
|
|
2023-07-21 05:53:17 +00:00
|
|
|
public FillMySqlDSForm(
|
2023-08-18 05:18:35 +00:00
|
|
|
environment = this.dataManager.defaultEnviorment,
|
2023-07-21 05:53:17 +00:00
|
|
|
shouldAddTrailingSpaces = false,
|
|
|
|
|
) {
|
2022-05-31 05:33:59 +00:00
|
|
|
const hostAddress = shouldAddTrailingSpaces
|
2023-08-18 05:18:35 +00:00
|
|
|
? this.dataManager.dsValues[environment].mysql_host + " "
|
|
|
|
|
: this.dataManager.dsValues[environment].mysql_host;
|
2022-05-31 05:33:59 +00:00
|
|
|
const databaseName = shouldAddTrailingSpaces
|
2023-08-18 05:18:35 +00:00
|
|
|
? this.dataManager.dsValues[environment].mysql_databaseName + " "
|
|
|
|
|
: this.dataManager.dsValues[environment].mysql_databaseName;
|
2023-05-19 18:37:06 +00:00
|
|
|
|
2024-04-30 07:45:11 +00:00
|
|
|
this.agHelper.ClearNType(this._host(), hostAddress);
|
|
|
|
|
this.agHelper.ClearNType(
|
2023-07-11 05:14:13 +00:00
|
|
|
this._port,
|
2023-08-18 05:18:35 +00:00
|
|
|
this.dataManager.dsValues[environment].mysql_port.toString(),
|
2023-07-11 05:14:13 +00:00
|
|
|
);
|
2023-08-08 09:14:46 +00:00
|
|
|
this.agHelper.ClearNType(this._databaseName, databaseName);
|
2024-04-30 07:45:11 +00:00
|
|
|
this.agHelper.ClearNType(
|
2023-07-11 05:14:13 +00:00
|
|
|
this._username,
|
2023-08-18 05:18:35 +00:00
|
|
|
this.dataManager.dsValues[environment].mysql_username,
|
2023-07-21 05:53:17 +00:00
|
|
|
);
|
2024-04-30 07:45:11 +00:00
|
|
|
this.agHelper.ClearNType(
|
|
|
|
|
this._password,
|
2023-08-18 05:18:35 +00:00
|
|
|
this.dataManager.dsValues[environment].mysql_password,
|
2023-07-11 05:14:13 +00:00
|
|
|
);
|
2022-05-31 05:33:59 +00:00
|
|
|
}
|
|
|
|
|
|
2023-09-20 08:42:11 +00:00
|
|
|
public FillMsSqlDSForm(
|
|
|
|
|
environment = this.dataManager.defaultEnviorment,
|
|
|
|
|
leaveDBNameEmpty = true,
|
|
|
|
|
) {
|
2024-04-30 07:45:11 +00:00
|
|
|
this.agHelper.ClearNType(
|
2023-09-14 11:23:42 +00:00
|
|
|
this._host(),
|
2023-08-18 05:18:35 +00:00
|
|
|
this.dataManager.dsValues[environment].mssql_host,
|
2023-07-21 05:53:17 +00:00
|
|
|
);
|
2024-04-30 07:45:11 +00:00
|
|
|
this.agHelper.ClearNType(
|
2023-07-11 05:14:13 +00:00
|
|
|
this._port,
|
2023-08-18 05:18:35 +00:00
|
|
|
this.dataManager.dsValues[environment].mssql_port.toString(),
|
2023-07-11 05:14:13 +00:00
|
|
|
);
|
2023-09-20 08:42:11 +00:00
|
|
|
|
|
|
|
|
if (leaveDBNameEmpty) {
|
|
|
|
|
this.agHelper.ClearTextField(this._databaseName);
|
|
|
|
|
} else {
|
|
|
|
|
const databaseName =
|
|
|
|
|
this.dataManager.dsValues[environment].mssql_databaseName;
|
|
|
|
|
this.agHelper.ClearNType(this._databaseName, databaseName);
|
|
|
|
|
}
|
2024-04-30 07:45:11 +00:00
|
|
|
this.agHelper.ClearNType(
|
2023-07-11 05:14:13 +00:00
|
|
|
this._username,
|
2023-08-18 05:18:35 +00:00
|
|
|
this.dataManager.dsValues[environment].mssql_username,
|
2023-07-11 05:14:13 +00:00
|
|
|
);
|
2024-04-30 07:45:11 +00:00
|
|
|
this.agHelper.ClearNType(
|
2023-07-11 05:14:13 +00:00
|
|
|
this._password,
|
2023-08-18 05:18:35 +00:00
|
|
|
this.dataManager.dsValues[environment].mssql_password,
|
2023-07-11 05:14:13 +00:00
|
|
|
);
|
2023-03-16 18:28:32 +00:00
|
|
|
}
|
|
|
|
|
|
2023-03-18 19:42:01 +00:00
|
|
|
public FillAirtableDSForm() {
|
|
|
|
|
this.ValidateNSelectDropdown(
|
2023-06-01 14:23:35 +00:00
|
|
|
"Authentication type",
|
2023-05-19 18:37:06 +00:00
|
|
|
"Please select an option",
|
2023-06-15 10:04:08 +00:00
|
|
|
"Personal access token",
|
2023-03-18 19:42:01 +00:00
|
|
|
);
|
2023-08-21 07:49:28 +00:00
|
|
|
this.agHelper.TypeText(
|
|
|
|
|
this.locator._inputFieldByName("Bearer token") +
|
|
|
|
|
"//" +
|
|
|
|
|
this.locator._inputField,
|
2023-03-18 19:42:01 +00:00
|
|
|
Cypress.env("AIRTABLE_BEARER"),
|
|
|
|
|
);
|
|
|
|
|
this.agHelper.Sleep();
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-18 05:18:35 +00:00
|
|
|
public FillArangoDSForm(environment = this.dataManager.defaultEnviorment) {
|
2024-04-30 07:45:11 +00:00
|
|
|
this.agHelper.ClearNType(
|
2023-09-14 11:23:42 +00:00
|
|
|
this._host(),
|
2023-08-18 05:18:35 +00:00
|
|
|
this.dataManager.dsValues[environment].arango_host,
|
2023-07-21 05:53:17 +00:00
|
|
|
);
|
2024-04-30 07:45:11 +00:00
|
|
|
this.agHelper.ClearNType(
|
2023-07-11 05:14:13 +00:00
|
|
|
this._port,
|
2023-08-18 05:18:35 +00:00
|
|
|
this.dataManager.dsValues[environment].arango_port.toString(),
|
2023-07-11 05:14:13 +00:00
|
|
|
);
|
2023-03-28 20:07:07 +00:00
|
|
|
//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"));
|
2024-04-30 07:45:11 +00:00
|
|
|
this.agHelper.ClearNType(
|
2023-07-11 05:14:13 +00:00
|
|
|
this._username,
|
2023-08-18 05:18:35 +00:00
|
|
|
this.dataManager.dsValues[environment].arango_username,
|
2023-07-11 05:14:13 +00:00
|
|
|
);
|
2024-04-30 07:45:11 +00:00
|
|
|
this.agHelper.ClearNType(
|
2023-07-11 05:14:13 +00:00
|
|
|
this._password,
|
2023-08-18 05:18:35 +00:00
|
|
|
this.dataManager.dsValues[environment].arango_password,
|
2023-07-11 05:14:13 +00:00
|
|
|
);
|
2023-03-28 20:07:07 +00:00
|
|
|
}
|
|
|
|
|
|
2023-08-18 05:18:35 +00:00
|
|
|
public FillFirestoreDSForm(environment = this.dataManager.defaultEnviorment) {
|
2023-08-21 07:49:28 +00:00
|
|
|
this.agHelper.TypeText(
|
|
|
|
|
this.locator._inputFieldByName("Database URL") +
|
|
|
|
|
"//" +
|
|
|
|
|
this.locator._inputField,
|
2023-08-18 05:18:35 +00:00
|
|
|
this.dataManager.dsValues[environment].firestore_database_url,
|
2023-04-04 15:56:57 +00:00
|
|
|
);
|
2023-08-21 07:49:28 +00:00
|
|
|
this.agHelper.TypeText(
|
|
|
|
|
this.locator._inputFieldByName("Project Id") +
|
|
|
|
|
"//" +
|
|
|
|
|
this.locator._inputField,
|
2023-08-18 05:18:35 +00:00
|
|
|
this.dataManager.dsValues[environment].firestore_projectID,
|
2022-08-04 04:48:15 +00:00
|
|
|
);
|
2023-06-20 08:58:06 +00:00
|
|
|
this.agHelper.UpdateFieldInput(
|
2023-05-19 18:37:06 +00:00
|
|
|
this.locator._inputFieldByName("Service account credentials"),
|
2023-09-25 14:32:54 +00:00
|
|
|
JSON.stringify(
|
|
|
|
|
this.dataManager.dsValues[environment].firestore_serviceaccountkey,
|
|
|
|
|
),
|
2022-08-04 04:48:15 +00:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-21 05:53:17 +00:00
|
|
|
public FillElasticSearchDSForm(
|
2023-08-18 05:18:35 +00:00
|
|
|
environment = this.dataManager.defaultEnviorment,
|
2023-07-21 05:53:17 +00:00
|
|
|
) {
|
2024-04-30 07:45:11 +00:00
|
|
|
this.agHelper.ClearNType(
|
2023-09-14 11:23:42 +00:00
|
|
|
this._host(),
|
2023-08-18 05:18:35 +00:00
|
|
|
this.dataManager.dsValues[environment].elastic_host,
|
2023-07-21 05:53:17 +00:00
|
|
|
);
|
2024-04-30 07:45:11 +00:00
|
|
|
this.agHelper.ClearNType(
|
2023-07-11 05:14:13 +00:00
|
|
|
this._port,
|
2023-08-18 05:18:35 +00:00
|
|
|
this.dataManager.dsValues[environment].elastic_port.toString(),
|
2023-07-11 05:14:13 +00:00
|
|
|
);
|
2024-04-30 07:45:11 +00:00
|
|
|
this.agHelper.ClearNType(
|
2023-07-11 05:14:13 +00:00
|
|
|
this._username,
|
2023-08-18 05:18:35 +00:00
|
|
|
this.dataManager.dsValues[environment].elastic_username,
|
2023-07-11 05:14:13 +00:00
|
|
|
);
|
2024-04-30 07:45:11 +00:00
|
|
|
this.agHelper.ClearNType(
|
2023-07-11 05:14:13 +00:00
|
|
|
this._password,
|
2023-08-18 05:18:35 +00:00
|
|
|
this.dataManager.dsValues[environment].elastic_password,
|
2023-07-11 05:14:13 +00:00
|
|
|
);
|
2023-04-06 04:07:04 +00:00
|
|
|
}
|
|
|
|
|
|
2023-07-21 05:53:17 +00:00
|
|
|
public FillUnAuthenticatedGraphQLDSForm(
|
2023-08-18 05:18:35 +00:00
|
|
|
environment = this.dataManager.defaultEnviorment,
|
2023-09-04 13:30:21 +00:00
|
|
|
enterOrSelectUrl: "enter" | "select" = "enter",
|
|
|
|
|
dsNameToSelect = "",
|
2024-12-03 03:51:43 +00:00
|
|
|
renameCallback?: (queryName: string) => void,
|
2023-07-21 05:53:17 +00:00
|
|
|
) {
|
2023-03-15 05:03:34 +00:00
|
|
|
this.agHelper.GetNClick(this._createBlankGraphQL);
|
2023-09-02 12:24:26 +00:00
|
|
|
cy.get("@guid").then((uid) => {
|
2024-12-03 03:51:43 +00:00
|
|
|
const queryName = "GraphQL_API" + "_" + uid;
|
|
|
|
|
if (typeof renameCallback === "function") {
|
|
|
|
|
renameCallback(queryName);
|
|
|
|
|
} else {
|
|
|
|
|
this.agHelper.RenameQuery(queryName);
|
|
|
|
|
}
|
2023-09-02 12:24:26 +00:00
|
|
|
|
2023-09-04 13:30:21 +00:00
|
|
|
if (enterOrSelectUrl == "enter")
|
|
|
|
|
this.apiPage.EnterURL(
|
|
|
|
|
this.dataManager.dsValues[environment].GraphqlApiUrl_TED,
|
|
|
|
|
);
|
2024-02-15 06:21:25 +00:00
|
|
|
else if (enterOrSelectUrl == "select") {
|
2024-12-03 03:51:43 +00:00
|
|
|
this.agHelper.GetNClick(ApiEditor.dataSourceField);
|
2024-02-15 06:21:25 +00:00
|
|
|
this.agHelper.GetNClick(this._graphQlDsHintOption(dsNameToSelect));
|
|
|
|
|
}
|
2023-09-04 13:30:21 +00:00
|
|
|
|
2023-09-02 12:24:26 +00:00
|
|
|
this.assertHelper.AssertNetworkStatus("@createNewApi", 201);
|
2024-12-03 03:51:43 +00:00
|
|
|
cy.wrap(queryName).as("dsName");
|
2023-09-02 12:24:26 +00:00
|
|
|
});
|
2023-03-15 05:03:34 +00:00
|
|
|
}
|
|
|
|
|
|
2023-09-04 13:30:21 +00:00
|
|
|
public FillAuthenticatedGrapgQLURL(
|
2023-08-18 05:18:35 +00:00
|
|
|
environment = this.dataManager.defaultEnviorment,
|
2023-03-15 05:03:34 +00:00
|
|
|
) {
|
2023-08-21 07:49:28 +00:00
|
|
|
this.agHelper.TypeText(
|
|
|
|
|
this.locator._inputFieldByName("URL") + "//" + this.locator._inputField,
|
2023-08-18 05:18:35 +00:00
|
|
|
this.dataManager.dsValues[environment].GraphqlApiUrl_TED,
|
2023-03-15 05:03:34 +00:00
|
|
|
);
|
2023-09-04 13:30:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public CreateNFillAuthenticatedGraphQLDSForm(
|
|
|
|
|
dataSourceName: string,
|
|
|
|
|
hKey: string,
|
|
|
|
|
hValue: string,
|
|
|
|
|
environment = this.dataManager.defaultEnviorment,
|
|
|
|
|
) {
|
|
|
|
|
this.FillAuthenticatedGrapgQLURL(environment);
|
2023-03-15 05:03:34 +00:00
|
|
|
|
2024-04-30 07:45:11 +00:00
|
|
|
this.agHelper.ClearNType(this._graphQLHeaderKey, hKey);
|
|
|
|
|
this.agHelper.ClearNType(this._graphQLHeaderValue, hValue);
|
2023-03-15 05:03:34 +00:00
|
|
|
cy.get("@guid").then((uid: any) => {
|
|
|
|
|
dataSourceName = dataSourceName + " " + uid;
|
2024-12-03 03:51:43 +00:00
|
|
|
this.agHelper.RenameDatasource(dataSourceName);
|
2023-03-15 05:03:34 +00:00
|
|
|
this.SaveDatasource();
|
|
|
|
|
cy.wrap(dataSourceName).as("dsName");
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-18 05:18:35 +00:00
|
|
|
public FillRedisDSForm(environment = this.dataManager.defaultEnviorment) {
|
2024-04-30 07:45:11 +00:00
|
|
|
this.agHelper.ClearNType(
|
2023-09-14 11:23:42 +00:00
|
|
|
this._host(),
|
2023-08-18 05:18:35 +00:00
|
|
|
this.dataManager.dsValues[environment].redis_host,
|
2023-07-21 05:53:17 +00:00
|
|
|
);
|
2024-04-30 07:45:11 +00:00
|
|
|
this.agHelper.ClearNType(
|
2023-07-11 05:14:13 +00:00
|
|
|
this._port,
|
2023-08-18 05:18:35 +00:00
|
|
|
this.dataManager.dsValues[environment].redis_port.toString(),
|
2023-07-11 05:14:13 +00:00
|
|
|
);
|
2023-04-25 18:24:36 +00:00
|
|
|
}
|
|
|
|
|
|
2023-06-30 18:46:57 +00:00
|
|
|
public FillS3DSForm() {
|
2024-04-30 07:45:11 +00:00
|
|
|
this.agHelper.ClearNType(this._username, Cypress.env("S3_ACCESS_KEY"));
|
|
|
|
|
this.agHelper.ClearNType(this._password, Cypress.env("S3_SECRET_KEY"));
|
2023-06-30 18:46:57 +00:00
|
|
|
}
|
|
|
|
|
|
2023-09-04 13:30:21 +00:00
|
|
|
public FillTwilioDSForm(environment = this.dataManager.defaultEnviorment) {
|
2023-08-22 17:22:36 +00:00
|
|
|
this.ValidateNSelectDropdown("Authentication type", "", "Basic auth");
|
2024-04-30 07:45:11 +00:00
|
|
|
this.agHelper.ClearNType(
|
2023-08-22 17:22:36 +00:00
|
|
|
this._username,
|
|
|
|
|
this.dataManager.dsValues[environment].twilio_username.toString(),
|
|
|
|
|
);
|
2024-04-30 07:45:11 +00:00
|
|
|
this.agHelper.ClearNType(
|
2023-08-22 17:22:36 +00:00
|
|
|
this._password,
|
|
|
|
|
this.dataManager.dsValues[environment].twilio_password.toString(),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-28 12:15:21 +00:00
|
|
|
public TestSaveDatasource(expectedRes = true, isReconnectModal = false) {
|
2022-05-18 10:39:42 +00:00
|
|
|
this.TestDatasource(expectedRes);
|
2023-09-28 12:15:21 +00:00
|
|
|
this.SaveDatasource(isReconnectModal);
|
2022-05-18 10:39:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public TestDatasource(expectedRes = true) {
|
2023-07-06 05:13:15 +00:00
|
|
|
this.agHelper.Sleep(500); //bit of time for CI!
|
2022-08-24 14:23:41 +00:00
|
|
|
this.agHelper.GetNClick(this._testDs, 0, false, 0);
|
2023-06-15 13:21:11 +00:00
|
|
|
this.agHelper.AssertNetworkDataSuccess("@testDatasource", expectedRes);
|
2023-01-05 12:36:26 +00:00
|
|
|
if (expectedRes) {
|
|
|
|
|
this.agHelper.AssertContains("datasource is valid");
|
|
|
|
|
}
|
2022-05-18 10:39:42 +00:00
|
|
|
}
|
|
|
|
|
|
2023-09-28 12:15:21 +00:00
|
|
|
public SaveDatasource(isReconnectModal = false, isSavingEnvInOldDS = false) {
|
2023-07-06 05:13:15 +00:00
|
|
|
this.agHelper.Sleep(500); //bit of time for CI!
|
2022-11-30 05:59:45 +00:00
|
|
|
this.agHelper.GetNClick(this._saveDs);
|
2023-09-28 12:15:21 +00:00
|
|
|
if (!isReconnectModal) {
|
2023-07-04 16:33:31 +00:00
|
|
|
this.assertHelper.AssertNetworkStatus("@saveDatasource", 201);
|
2023-07-21 05:53:17 +00:00
|
|
|
if (!isSavingEnvInOldDS)
|
|
|
|
|
this.agHelper.AssertContains("datasource created");
|
2023-07-04 16:33:31 +00:00
|
|
|
} else {
|
|
|
|
|
this.assertHelper.AssertNetworkStatus("@updateDatasource", 200);
|
2023-06-28 10:16:17 +00:00
|
|
|
}
|
2023-09-11 09:54:32 +00:00
|
|
|
}
|
2022-05-18 10:39:42 +00:00
|
|
|
|
2023-09-11 09:54:32 +00:00
|
|
|
public AssertSaveDSButtonDisability(isDisabled = true) {
|
|
|
|
|
this.agHelper.AssertElementEnabledDisabled(this._saveDs, 0, isDisabled);
|
2022-05-18 10:39:42 +00:00
|
|
|
}
|
|
|
|
|
|
2022-11-28 05:12:27 +00:00
|
|
|
public AuthAPISaveAndAuthorize() {
|
2023-09-12 06:18:58 +00:00
|
|
|
cy.get(this._saveDs).click();
|
2023-06-18 04:55:16 +00:00
|
|
|
this.assertHelper.AssertNetworkStatus("@saveDatasource", 201);
|
2022-11-30 05:59:45 +00:00
|
|
|
}
|
|
|
|
|
|
2022-12-30 10:23:24 +00:00
|
|
|
public UpdateDatasource() {
|
2022-11-30 05:59:45 +00:00
|
|
|
this.agHelper.GetNClick(this._saveDs);
|
2023-06-18 04:55:16 +00:00
|
|
|
// this.assertHelper.AssertNetworkStatus("@updateDatasource", 200);
|
2022-11-30 05:59:45 +00:00
|
|
|
this.agHelper.AssertContains("datasource updated");
|
2022-11-28 05:12:27 +00:00
|
|
|
}
|
|
|
|
|
|
2023-09-20 08:42:11 +00:00
|
|
|
public DeleteDatasourceFromWithinDS(
|
2023-05-22 12:05:59 +00:00
|
|
|
datasourceName: string,
|
2023-10-25 14:03:07 +00:00
|
|
|
expectedRes: number | number[] = 200 || 409 || [200, 409],
|
2023-05-22 12:05:59 +00:00
|
|
|
) {
|
2023-11-23 10:16:13 +00:00
|
|
|
EditorNavigation.SelectEntityByName(datasourceName, EntityType.Datasource);
|
2023-05-22 12:05:59 +00:00
|
|
|
this.agHelper.Sleep(); //for the Datasource page to open
|
2023-11-15 02:31:12 +00:00
|
|
|
this.DeleteDSDirectly(expectedRes, false);
|
2023-05-22 12:05:59 +00:00
|
|
|
}
|
|
|
|
|
|
2023-07-24 10:29:05 +00:00
|
|
|
// this initiates saving via the cancel button.
|
|
|
|
|
public cancelDSEditAndAssertModalPopUp(
|
|
|
|
|
shouldPopUpBeShown = false,
|
|
|
|
|
shouldSave = false,
|
|
|
|
|
) {
|
|
|
|
|
// click cancel button.
|
|
|
|
|
this.agHelper.GetNClick(this._cancelEditDatasourceButton, 0, false, 200);
|
|
|
|
|
|
|
|
|
|
if (shouldPopUpBeShown) {
|
|
|
|
|
this.AssertDatasourceSaveModalVisibilityAndSave(shouldSave);
|
|
|
|
|
} else {
|
|
|
|
|
this.AssertDSDialogVisibility(false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-22 12:05:59 +00:00
|
|
|
public DeleteDSDirectly(
|
2023-10-25 14:03:07 +00:00
|
|
|
expectedRes: number | number[] = 200 || 409 || [200, 409],
|
2023-08-08 09:14:46 +00:00
|
|
|
toNavigateToDSInfoPage = true,
|
2023-05-22 12:05:59 +00:00
|
|
|
) {
|
2023-08-08 09:14:46 +00:00
|
|
|
toNavigateToDSInfoPage &&
|
|
|
|
|
this.agHelper.GetNClick(this._cancelEditDatasourceButton, 0, true, 200);
|
|
|
|
|
this.agHelper.GetNClick(this._contextMenuDSReviewPage);
|
2023-05-22 12:05:59 +00:00
|
|
|
this.agHelper.GetNClick(this._contextMenuDelete);
|
|
|
|
|
this.agHelper.GetNClick(this.locator._visibleTextSpan("Are you sure?"));
|
|
|
|
|
this.ValidateDSDeletion(expectedRes);
|
|
|
|
|
}
|
2023-06-15 13:21:11 +00:00
|
|
|
|
2023-05-22 12:05:59 +00:00
|
|
|
public ValidateDSDeletion(expectedRes: number | number[] = 200) {
|
2023-10-25 14:03:07 +00:00
|
|
|
this.assertHelper
|
|
|
|
|
.AssertNetworkStatus("@deleteDatasource", expectedRes)
|
|
|
|
|
.then((responseStatus) => {
|
|
|
|
|
this.agHelper.AssertContains(
|
|
|
|
|
responseStatus === 200
|
|
|
|
|
? "datasource deleted successfully"
|
2024-07-11 14:12:27 +00:00
|
|
|
: "Cannot delete datasource",
|
2023-10-25 14:03:07 +00:00
|
|
|
);
|
|
|
|
|
});
|
2022-05-31 05:33:59 +00:00
|
|
|
}
|
|
|
|
|
|
2023-09-08 19:07:23 +00:00
|
|
|
public AssertDSInActiveList(dsName: string | RegExp) {
|
2023-11-28 11:11:54 +00:00
|
|
|
AppSidebar.navigate(AppSidebarButton.Data);
|
2023-06-15 13:21:11 +00:00
|
|
|
return this.agHelper.GetNAssertContains(this._datasourceCard, dsName);
|
2022-05-18 10:39:42 +00:00
|
|
|
}
|
|
|
|
|
|
2023-03-05 03:22:42 +00:00
|
|
|
CreateQueryAfterDSSaved(query = "", queryName = "") {
|
|
|
|
|
this.agHelper.GetNClick(this._createQuery);
|
2023-12-05 05:50:36 +00:00
|
|
|
// Check if page selection is open (when multiple pages in app)
|
|
|
|
|
cy.get("body").then(($body) => {
|
|
|
|
|
if ($body.find(this._pageSelectionMenu).length > 0) {
|
|
|
|
|
// Select the current page
|
|
|
|
|
cy.get(this._pageSelectionMenu)
|
|
|
|
|
.find(this._pageSelectMenuItem)
|
|
|
|
|
.first()
|
|
|
|
|
.click();
|
|
|
|
|
}
|
|
|
|
|
});
|
2023-06-18 04:55:16 +00:00
|
|
|
//this.assertHelper.AssertNetworkStatus("@createNewApi", 201);
|
2023-08-10 07:06:03 +00:00
|
|
|
this.AssertRunButtonVisibility();
|
2024-12-03 03:51:43 +00:00
|
|
|
if (queryName) this.agHelper.RenameQuery(queryName);
|
2023-03-05 03:22:42 +00:00
|
|
|
if (query) {
|
|
|
|
|
this.EnterQuery(query);
|
2023-06-30 18:46:57 +00:00
|
|
|
this.AssertRunButtonDisability(false);
|
2023-03-05 03:22:42 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-29 06:34:40 +00:00
|
|
|
public AssertRunButtonVisibility() {
|
2023-08-10 07:06:03 +00:00
|
|
|
this.agHelper.AssertElementVisibility(
|
2023-08-21 07:49:28 +00:00
|
|
|
this.locator._buttonByText("Run"),
|
2023-08-10 07:06:03 +00:00
|
|
|
true,
|
|
|
|
|
0,
|
|
|
|
|
20000,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-01 11:12:44 +00:00
|
|
|
public CreateQueryForDS(
|
|
|
|
|
datasourceName: string,
|
|
|
|
|
query = "",
|
|
|
|
|
queryName = "",
|
|
|
|
|
cancelEditDs = true,
|
|
|
|
|
) {
|
2023-12-05 05:50:36 +00:00
|
|
|
EditorNavigation.SelectEntityByName(datasourceName, EntityType.Datasource);
|
2023-08-01 11:12:44 +00:00
|
|
|
if (cancelEditDs) {
|
2023-12-05 05:50:36 +00:00
|
|
|
this.cancelIfEditing();
|
2023-08-01 11:12:44 +00:00
|
|
|
}
|
2023-07-26 18:13:54 +00:00
|
|
|
this.CreateQueryAfterDSSaved(query, queryName);
|
|
|
|
|
}
|
|
|
|
|
|
2023-12-05 05:50:36 +00:00
|
|
|
public GeneratePageForDS(datasourceName: string) {
|
|
|
|
|
EditorNavigation.SelectEntityByName(datasourceName, EntityType.Datasource);
|
|
|
|
|
this.cancelIfEditing();
|
|
|
|
|
this.agHelper.GetNClick(this._datasourceCardGeneratePageBtn);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private cancelIfEditing() {
|
|
|
|
|
cy.get("body").then(($body) => {
|
|
|
|
|
if ($body.find(this._cancelEditDatasourceButton).length > 0) {
|
|
|
|
|
this.agHelper.GetNClick(this._cancelEditDatasourceButton, 0, true, 200);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2022-10-20 12:08:48 +00:00
|
|
|
DeleteQuery(queryName: string) {
|
2024-01-12 14:43:58 +00:00
|
|
|
PageLeftPane.switchSegment(PagePaneSegment.Queries);
|
2023-08-04 03:46:59 +00:00
|
|
|
this.entityExplorer.ActionContextMenuByEntityName({
|
2023-06-15 13:21:11 +00:00
|
|
|
entityNameinLeftSidebar: queryName,
|
|
|
|
|
action: "Delete",
|
|
|
|
|
entityType: EntityItems.Query,
|
|
|
|
|
});
|
2022-10-20 12:08:48 +00:00
|
|
|
}
|
|
|
|
|
|
2022-05-18 10:39:42 +00:00
|
|
|
public ValidateNSelectDropdown(
|
|
|
|
|
ddTitle: string,
|
2023-05-19 18:37:06 +00:00
|
|
|
currentValue: string,
|
2022-05-18 10:39:42 +00:00
|
|
|
newValue = "",
|
|
|
|
|
) {
|
|
|
|
|
if (currentValue)
|
|
|
|
|
cy.xpath(this._visibleTextSpan(currentValue))
|
2023-05-19 18:37:06 +00:00
|
|
|
//.scrollIntoView()
|
|
|
|
|
.should("exist", currentValue + " dropdown value not present");
|
|
|
|
|
if (newValue != "") {
|
2023-05-24 12:30:39 +00:00
|
|
|
this.agHelper.GetNClick(this._dropdownTitle(ddTitle));
|
2023-05-19 18:37:06 +00:00
|
|
|
//cy.xpath(this._dropdown(currentValue)).last().click({ force: true });
|
|
|
|
|
//to expand the dropdown
|
2023-05-24 12:30:39 +00:00
|
|
|
//this.agHelper.GetNClick(this._queryOption(newValue))
|
2023-05-19 18:37:06 +00:00
|
|
|
cy.xpath(this._queryOption(newValue)).last().click({ force: true }); //to select the new value
|
2022-04-03 16:43:20 +00:00
|
|
|
}
|
2022-05-18 10:39:42 +00:00
|
|
|
}
|
|
|
|
|
|
2023-07-26 18:13:54 +00:00
|
|
|
public ValidateReviewModeConfig(
|
|
|
|
|
dsName: "PostgreSQL" | "MongoDB",
|
2023-08-18 05:18:35 +00:00
|
|
|
environment = this.dataManager.defaultEnviorment,
|
2023-07-26 18:13:54 +00:00
|
|
|
) {
|
|
|
|
|
if (dsName === "PostgreSQL") {
|
|
|
|
|
this.ValidatePostgresDSForm(environment);
|
|
|
|
|
} else if (dsName === "MongoDB") {
|
|
|
|
|
this.ValidateMongoForm(environment);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-11 16:39:13 +00:00
|
|
|
public ReconnectSingleDSNAssert(
|
|
|
|
|
dbName: string,
|
|
|
|
|
dsName: "PostgreSQL" | "MySQL" | "MongoDB",
|
|
|
|
|
) {
|
2023-07-04 16:33:31 +00:00
|
|
|
this.ReconnectModalValidation(dbName, dsName);
|
|
|
|
|
if (dsName == "PostgreSQL") this.FillPostgresDSForm();
|
|
|
|
|
else if (dsName == "MySQL") this.FillMySqlDSForm();
|
2023-07-11 16:39:13 +00:00
|
|
|
else if (dsName == "MongoDB") this.FillMongoDSForm();
|
2023-09-28 12:15:21 +00:00
|
|
|
this.TestSaveDatasource(true, true);
|
2024-01-24 06:44:16 +00:00
|
|
|
this.assertHelper.AssertNetworkStatus("@getConsolidatedData", 200);
|
2023-07-04 16:33:31 +00:00
|
|
|
this.assertHelper.AssertNetworkStatus("getWorkspace");
|
|
|
|
|
}
|
2024-07-10 08:52:39 +00:00
|
|
|
|
2023-07-04 16:33:31 +00:00
|
|
|
public ReconnectModalValidation(
|
|
|
|
|
dbName: string,
|
2023-07-11 16:39:13 +00:00
|
|
|
dsName: "PostgreSQL" | "MySQL" | "MongoDB",
|
2023-07-04 16:33:31 +00:00
|
|
|
) {
|
2023-07-06 20:10:02 +00:00
|
|
|
this.WaitForReconnectModalToAppear();
|
2023-08-10 07:06:03 +00:00
|
|
|
this.agHelper.AssertElementVisibility(
|
2023-06-21 17:37:21 +00:00
|
|
|
this._activeDSListReconnectModal(dsName),
|
|
|
|
|
);
|
2023-08-10 07:06:03 +00:00
|
|
|
this.agHelper.AssertElementVisibility(
|
2023-06-21 17:37:21 +00:00
|
|
|
this._activeDSListReconnectModal(dbName),
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
//Checking if tooltip for Ds name & icon is present (useful in cases of long name for ds)
|
|
|
|
|
this.agHelper.AssertText(this._reconnectModalDSToolTip, "text", dbName);
|
2023-08-10 07:06:03 +00:00
|
|
|
this.agHelper.AssertElementVisibility(this._reconnectModalDSToopTipIcon);
|
2023-07-04 16:33:31 +00:00
|
|
|
}
|
2023-06-21 17:37:21 +00:00
|
|
|
|
2023-07-06 20:10:02 +00:00
|
|
|
public WaitForReconnectModalToAppear() {
|
2023-08-10 07:06:03 +00:00
|
|
|
this.agHelper.AssertElementVisibility(this._reconnectModal);
|
|
|
|
|
this.agHelper.AssertElementVisibility(this._testDs); //Making sure modal is fully loaded
|
2023-07-06 20:10:02 +00:00
|
|
|
}
|
|
|
|
|
|
2023-07-07 17:58:16 +00:00
|
|
|
public ReconnectDSbyType(
|
2023-07-04 16:33:31 +00:00
|
|
|
dsName: "PostgreSQL" | "MySQL" | "MongoDB" | "S3" | "MongoDBUri",
|
|
|
|
|
) {
|
2023-07-06 20:10:02 +00:00
|
|
|
this.WaitForReconnectModalToAppear();
|
|
|
|
|
|
2023-07-04 16:33:31 +00:00
|
|
|
if (dsName !== "MongoDBUri")
|
|
|
|
|
this.agHelper.GetNClick(this.locator._visibleTextSpan(dsName));
|
|
|
|
|
else if (dsName == "MongoDBUri")
|
|
|
|
|
this.agHelper.GetNClick(this.locator._visibleTextSpan("MongoDB"));
|
|
|
|
|
|
|
|
|
|
const methodMap = {
|
|
|
|
|
PostgreSQL: this.FillPostgresDSForm,
|
|
|
|
|
MySQL: this.FillMySqlDSForm,
|
|
|
|
|
MongoDB: this.FillMongoDSForm,
|
|
|
|
|
S3: this.FillS3DSForm,
|
|
|
|
|
MongoDBUri: this.FillMongoDatasourceFormWithURI,
|
|
|
|
|
};
|
|
|
|
|
if (methodMap[dsName]) {
|
|
|
|
|
methodMap[dsName].call(this);
|
|
|
|
|
}
|
|
|
|
|
this.SaveDatasource(true);
|
2022-05-18 10:39:42 +00:00
|
|
|
}
|
|
|
|
|
|
2023-03-18 19:42:01 +00:00
|
|
|
RunQuery({
|
2023-03-11 07:01:39 +00:00
|
|
|
expectedStatus = true,
|
2023-03-23 11:32:18 +00:00
|
|
|
toValidateResponse = true,
|
2022-08-24 14:23:41 +00:00
|
|
|
waitTimeInterval = 500,
|
2023-03-18 19:42:01 +00:00
|
|
|
}: Partial<RunQueryParams> = {}) {
|
2023-06-30 18:46:57 +00:00
|
|
|
this.AssertRunButtonDisability(false);
|
2022-08-24 14:23:41 +00:00
|
|
|
this.agHelper.GetNClick(this._runQueryBtn, 0, true, waitTimeInterval);
|
2023-06-15 13:21:11 +00:00
|
|
|
this.agHelper.AssertElementAbsence(
|
|
|
|
|
this.locator._cancelActionExecution,
|
|
|
|
|
10000,
|
|
|
|
|
); //For the run to give response
|
2022-08-24 14:23:41 +00:00
|
|
|
if (toValidateResponse) {
|
2023-03-18 19:42:01 +00:00
|
|
|
this.agHelper.Sleep();
|
2023-08-21 07:49:28 +00:00
|
|
|
this.assertHelper.AssertNetworkExecutionSuccess(
|
2022-08-24 14:23:41 +00:00
|
|
|
"@postExecute",
|
|
|
|
|
expectedStatus,
|
|
|
|
|
);
|
|
|
|
|
}
|
2022-05-31 05:33:59 +00:00
|
|
|
}
|
|
|
|
|
|
2023-06-08 09:09:19 +00:00
|
|
|
AssertRunButtonDisability(disabled = false) {
|
2023-06-30 18:46:57 +00:00
|
|
|
this.agHelper.AssertElementEnabledDisabled(this._runQueryBtn, 0, disabled);
|
2023-06-08 09:09:19 +00:00
|
|
|
}
|
|
|
|
|
|
2022-05-31 05:33:59 +00:00
|
|
|
public ReadQueryTableResponse(index: number, timeout = 100) {
|
|
|
|
|
//timeout can be sent higher values incase of larger tables
|
|
|
|
|
this.agHelper.Sleep(timeout); //Settling time for table!
|
chore: upgrade to prettier v2 + enforce import types (#21013)Co-authored-by: Satish Gandham <hello@satishgandham.com> Co-authored-by: Satish Gandham <satish.iitg@gmail.com>
## Description
This PR upgrades Prettier to v2 + enforces TypeScript’s [`import
type`](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-8.html#type-only-imports-and-export)
syntax where applicable. It’s submitted as a separate PR so we can merge
it easily.
As a part of this PR, we reformat the codebase heavily:
- add `import type` everywhere where it’s required, and
- re-format the code to account for Prettier 2’s breaking changes:
https://prettier.io/blog/2020/03/21/2.0.0.html#breaking-changes
This PR is submitted against `release` to make sure all new code by team
members will adhere to new formatting standards, and we’ll have fewer
conflicts when merging `bundle-optimizations` into `release`. (I’ll
merge `release` back into `bundle-optimizations` once this PR is
merged.)
### Why is this needed?
This PR is needed because, for the Lodash optimization from
https://github.com/appsmithorg/appsmith/commit/7cbb12af886621256224be0c93e6a465dd710ad3,
we need to use `import type`. Otherwise, `babel-plugin-lodash` complains
that `LoDashStatic` is not a lodash function.
However, just using `import type` in the current codebase will give you
this:
<img width="962" alt="Screenshot 2023-03-08 at 17 45 59"
src="https://user-images.githubusercontent.com/2953267/223775744-407afa0c-e8b9-44a1-90f9-b879348da57f.png">
That’s because Prettier 1 can’t parse `import type` at all. To parse it,
we need to upgrade to Prettier 2.
### Why enforce `import type`?
Apart from just enabling `import type` support, this PR enforces
specifying `import type` everywhere it’s needed. (Developers will get
immediate TypeScript and ESLint errors when they forget to do so.)
I’m doing this because I believe `import type` improves DX and makes
refactorings easier.
Let’s say you had a few imports like below. Can you tell which of these
imports will increase the bundle size? (Tip: it’s not all of them!)
```ts
// app/client/src/workers/Linting/utils.ts
import { Position } from "codemirror";
import { LintError as JSHintError, LintOptions } from "jshint";
import { get, isEmpty, isNumber, keys, last, set } from "lodash";
```
It’s pretty hard, right?
What about now?
```ts
// app/client/src/workers/Linting/utils.ts
import type { Position } from "codemirror";
import type { LintError as JSHintError, LintOptions } from "jshint";
import { get, isEmpty, isNumber, keys, last, set } from "lodash";
```
Now, it’s clear that only `lodash` will be bundled.
This helps developers to see which imports are problematic, but it
_also_ helps with refactorings. Now, if you want to see where
`codemirror` is bundled, you can just grep for `import \{.*\} from
"codemirror"` – and you won’t get any type-only imports.
This also helps (some) bundlers. Upon transpiling, TypeScript erases
type-only imports completely. In some environment (not ours), this makes
the bundle smaller, as the bundler doesn’t need to bundle type-only
imports anymore.
## Type of change
- Chore (housekeeping or task changes that don't impact user perception)
## How Has This Been Tested?
This was tested to not break the build.
### Test Plan
> Add Testsmith test cases links that relate to this PR
### Issues raised during DP testing
> Link issues raised during DP testing for better visiblity and tracking
(copy link from comments dropped on this PR)
## Checklist:
### Dev activity
- [x] My code follows the style guidelines of this project
- [ ] I have performed a self-review of my own code
- [ ] 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
- [ ] 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:
- [ ] Test plan has been approved by relevant developers
- [ ] Test plan has been peer reviewed by QA
- [ ] Cypress test cases have been added and approved by either SDET or
manual QA
- [ ] Organized project review call with relevant stakeholders after
Round 1/2 of QA
- [ ] Added Test Plan Approved label after reveiwing all Cypress test
---------
Co-authored-by: Satish Gandham <hello@satishgandham.com>
Co-authored-by: Satish Gandham <satish.iitg@gmail.com>
2023-03-16 11:41:47 +00:00
|
|
|
return cy.xpath(this._queryTableResponse).eq(index).invoke("text");
|
2022-05-31 05:33:59 +00:00
|
|
|
}
|
|
|
|
|
|
2023-07-04 16:33:31 +00:00
|
|
|
public AssertQueryTableResponse(
|
|
|
|
|
index: number,
|
|
|
|
|
expectedValue: string,
|
|
|
|
|
timeout = 100,
|
|
|
|
|
) {
|
|
|
|
|
this.ReadQueryTableResponse(index, timeout).then(($cellData: any) => {
|
|
|
|
|
expect($cellData).to.eq(expectedValue);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-17 11:31:40 +00:00
|
|
|
public AssertQueryResponseHeaders(columnHeaders: string[]) {
|
|
|
|
|
columnHeaders.forEach(($header) =>
|
2023-08-10 07:06:03 +00:00
|
|
|
this.agHelper.AssertElementVisibility(this._queryResponseHeader($header)),
|
2022-06-17 11:31:40 +00:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-31 05:33:59 +00:00
|
|
|
public AssertJSONFormHeader(
|
|
|
|
|
rowindex: number,
|
|
|
|
|
colIndex: number,
|
|
|
|
|
headerString: string,
|
|
|
|
|
validateCellData: "" | string = "",
|
2022-06-06 05:59:15 +00:00
|
|
|
isMongo = false,
|
2022-05-31 05:33:59 +00:00
|
|
|
) {
|
2022-06-06 05:59:15 +00:00
|
|
|
let jsonHeaderString = "";
|
2023-12-29 12:19:20 +00:00
|
|
|
this.table
|
|
|
|
|
.ReadTableRowColumnData(rowindex, colIndex, "v2")
|
|
|
|
|
.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));
|
|
|
|
|
});
|
2022-05-18 10:39:42 +00:00
|
|
|
}
|
2022-06-17 06:12:18 +00:00
|
|
|
|
2024-09-17 08:52:32 +00:00
|
|
|
ToggleUsePreparedStatement(enable = true || false) {
|
2024-12-03 03:51:43 +00:00
|
|
|
this.pluginActionForm.toolbar.toggleSettings();
|
2023-09-19 19:26:11 +00:00
|
|
|
if (enable) this.agHelper.CheckUncheck(this._usePreparedStatement, true);
|
|
|
|
|
else this.agHelper.CheckUncheck(this._usePreparedStatement, false);
|
2022-06-17 06:12:18 +00:00
|
|
|
}
|
2022-07-06 05:54:00 +00:00
|
|
|
|
2023-08-21 07:49:28 +00:00
|
|
|
public EnterQuery(query: string, sleep = 500, toVerifySave = true) {
|
2023-08-10 07:06:03 +00:00
|
|
|
this.agHelper.UpdateCodeInput(
|
|
|
|
|
this.locator._codeEditorTarget,
|
|
|
|
|
query,
|
|
|
|
|
"query",
|
|
|
|
|
);
|
2023-08-21 07:49:28 +00:00
|
|
|
toVerifySave && this.agHelper.AssertAutoSave();
|
2023-02-02 07:59:24 +00:00
|
|
|
this.agHelper.Sleep(sleep); //waiting a bit before proceeding!
|
2023-08-21 07:49:28 +00:00
|
|
|
this.assertHelper.AssertNetworkStatus("@saveAction", 200);
|
2022-07-06 05:54:00 +00:00
|
|
|
}
|
2022-07-16 10:41:17 +00:00
|
|
|
|
2024-11-28 11:31:50 +00:00
|
|
|
public runQueryAndVerifyResponseViews({
|
|
|
|
|
count = 1,
|
|
|
|
|
operator = "eq",
|
|
|
|
|
responseTypes = ["TABLE", "JSON", "RAW"],
|
|
|
|
|
}: {
|
|
|
|
|
count?: number;
|
|
|
|
|
operator?: Parameters<
|
2024-12-03 09:34:54 +00:00
|
|
|
typeof BottomTabs.response.validateRecordCount
|
2024-11-28 11:31:50 +00:00
|
|
|
>[0]["operator"];
|
|
|
|
|
responseTypes?: ("TABLE" | "JSON" | "RAW")[];
|
|
|
|
|
} = {}) {
|
|
|
|
|
this.RunQuery();
|
|
|
|
|
|
2024-12-03 09:34:54 +00:00
|
|
|
BottomTabs.response.openResponseTypeMenu();
|
2024-11-28 11:31:50 +00:00
|
|
|
|
|
|
|
|
responseTypes.forEach((responseType) => {
|
|
|
|
|
this.agHelper.AssertElementVisibility(
|
2024-12-03 09:34:54 +00:00
|
|
|
BottomTabs.response.locators.responseTypeMenuItem(responseType),
|
2024-11-28 11:31:50 +00:00
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
|
2024-12-03 09:34:54 +00:00
|
|
|
BottomTabs.response.closeResponseTypeMenu();
|
2024-11-28 11:31:50 +00:00
|
|
|
|
2024-12-03 09:34:54 +00:00
|
|
|
BottomTabs.response.validateRecordCount({
|
2024-11-28 11:31:50 +00:00
|
|
|
count,
|
|
|
|
|
operator,
|
|
|
|
|
});
|
2022-07-16 10:41:17 +00:00
|
|
|
}
|
2022-07-29 08:48:25 +00:00
|
|
|
|
2022-08-04 04:48:15 +00:00
|
|
|
public CreateDataSource(
|
2023-03-18 19:42:01 +00:00
|
|
|
dsType:
|
|
|
|
|
| "Postgres"
|
|
|
|
|
| "Mongo"
|
|
|
|
|
| "MySql"
|
|
|
|
|
| "UnAuthenticatedGraphQL"
|
2023-09-04 13:30:21 +00:00
|
|
|
| "AuthenticatedGraph"
|
2023-03-18 19:42:01 +00:00
|
|
|
| "MsSql"
|
2023-03-28 20:07:07 +00:00
|
|
|
| "Airtable"
|
2023-07-21 05:53:17 +00:00
|
|
|
| "ArangoDB"
|
2023-04-06 04:07:04 +00:00
|
|
|
| "Firestore"
|
2023-04-25 18:24:36 +00:00
|
|
|
| "Elasticsearch"
|
2023-06-12 17:48:46 +00:00
|
|
|
| "Redis"
|
2023-06-30 18:46:57 +00:00
|
|
|
| "Oracle"
|
2023-08-22 17:22:36 +00:00
|
|
|
| "S3"
|
|
|
|
|
| "Twilio",
|
2022-08-04 04:48:15 +00:00
|
|
|
navigateToCreateNewDs = true,
|
2023-03-05 03:22:42 +00:00
|
|
|
testNSave = true,
|
2023-08-18 05:18:35 +00:00
|
|
|
environment = this.dataManager.defaultEnviorment,
|
2023-07-21 05:53:17 +00:00
|
|
|
assetEnvironmentSelected = false,
|
2023-07-25 08:34:37 +00:00
|
|
|
// function to be executed before filling the datasource form
|
|
|
|
|
preDSConfigAction?: (arg?: string) => void,
|
2022-08-04 04:48:15 +00:00
|
|
|
) {
|
2022-07-29 08:48:25 +00:00
|
|
|
let guid: any;
|
2022-09-19 05:32:06 +00:00
|
|
|
let dataSourceName = "";
|
2022-07-29 08:48:25 +00:00
|
|
|
this.agHelper.GenerateUUID();
|
2023-03-15 05:03:34 +00:00
|
|
|
navigateToCreateNewDs && this.NavigateToDSCreateNew();
|
|
|
|
|
|
2022-07-29 08:48:25 +00:00
|
|
|
cy.get("@guid").then((uid) => {
|
2023-03-15 05:03:34 +00:00
|
|
|
if (DataSourceKVP[dsType] != "GraphQL API") {
|
|
|
|
|
this.CreatePlugIn(DataSourceKVP[dsType]);
|
|
|
|
|
guid = uid;
|
|
|
|
|
dataSourceName = dsType + " " + guid;
|
2024-12-03 03:51:43 +00:00
|
|
|
this.agHelper.RenameDatasource(dataSourceName);
|
2023-07-25 08:34:37 +00:00
|
|
|
// Execute the preDSConfigAction if it is defined
|
|
|
|
|
if (!!preDSConfigAction) {
|
|
|
|
|
preDSConfigAction.bind(this)(environment);
|
|
|
|
|
}
|
2023-07-21 05:53:17 +00:00
|
|
|
if (assetEnvironmentSelected) {
|
|
|
|
|
this.agHelper.AssertSelectedTab(
|
|
|
|
|
this.locator.ds_editor_env_filter(environment),
|
|
|
|
|
"true",
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
if (DataSourceKVP[dsType] == "PostgreSQL")
|
|
|
|
|
this.FillPostgresDSForm(environment);
|
|
|
|
|
else if (DataSourceKVP[dsType] == "Oracle")
|
|
|
|
|
this.FillOracleDSForm(environment);
|
|
|
|
|
else if (DataSourceKVP[dsType] == "MySQL")
|
|
|
|
|
this.FillMySqlDSForm(environment);
|
|
|
|
|
else if (DataSourceKVP[dsType] == "MongoDB")
|
|
|
|
|
this.FillMongoDSForm(environment);
|
2023-03-16 18:28:32 +00:00
|
|
|
else if (DataSourceKVP[dsType] == "Microsoft SQL Server")
|
2023-09-20 19:11:08 +00:00
|
|
|
this.FillMsSqlDSForm(environment);
|
2023-03-18 19:42:01 +00:00
|
|
|
else if (DataSourceKVP[dsType] == "Airtable") this.FillAirtableDSForm();
|
2023-07-21 05:53:17 +00:00
|
|
|
else if (DataSourceKVP[dsType] == "ArangoDB")
|
|
|
|
|
this.FillArangoDSForm(environment);
|
2023-04-04 15:56:57 +00:00
|
|
|
else if (DataSourceKVP[dsType] == "Firestore")
|
2023-07-21 05:53:17 +00:00
|
|
|
this.FillFirestoreDSForm(environment);
|
2023-04-06 04:07:04 +00:00
|
|
|
else if (DataSourceKVP[dsType] == "Elasticsearch")
|
2023-07-21 05:53:17 +00:00
|
|
|
this.FillElasticSearchDSForm(environment);
|
|
|
|
|
else if (DataSourceKVP[dsType] == "Redis")
|
|
|
|
|
this.FillRedisDSForm(environment);
|
2023-06-30 18:46:57 +00:00
|
|
|
else if (DataSourceKVP[dsType] == "S3") this.FillS3DSForm();
|
2023-09-04 13:30:21 +00:00
|
|
|
else if (DataSourceKVP[dsType] == "Twilio") this.FillTwilioDSForm();
|
|
|
|
|
else if (DataSourceKVP[dsType] == "Authenticated GraphQL API")
|
|
|
|
|
this.FillAuthenticatedGrapgQLURL();
|
2023-03-15 05:03:34 +00:00
|
|
|
|
|
|
|
|
if (testNSave) {
|
|
|
|
|
this.TestSaveDatasource();
|
|
|
|
|
} else {
|
|
|
|
|
this.SaveDatasource();
|
|
|
|
|
}
|
2023-09-02 12:24:26 +00:00
|
|
|
cy.wrap(dataSourceName).as("dsName");
|
|
|
|
|
} else if (DataSourceKVP[dsType] == "GraphQL API") {
|
2023-07-21 05:53:17 +00:00
|
|
|
this.FillUnAuthenticatedGraphQLDSForm(environment);
|
2023-09-02 12:24:26 +00:00
|
|
|
}
|
2022-07-29 08:48:25 +00:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-05 03:22:42 +00:00
|
|
|
public CreateQueryFromOverlay(
|
|
|
|
|
dsName: string,
|
|
|
|
|
query = "",
|
|
|
|
|
queryName = "",
|
|
|
|
|
sleep = 500,
|
|
|
|
|
) {
|
2023-10-25 14:03:07 +00:00
|
|
|
this.agHelper.RemoveUIElement("EvaluatedPopUp"); //to close the evaluated pop-up
|
2023-08-04 03:46:59 +00:00
|
|
|
this.entityExplorer.CreateNewDsQuery(dsName);
|
2022-09-19 05:32:06 +00:00
|
|
|
if (query) {
|
2023-03-05 03:22:42 +00:00
|
|
|
this.EnterQuery(query, sleep);
|
2022-09-19 05:32:06 +00:00
|
|
|
}
|
2024-12-03 03:51:43 +00:00
|
|
|
if (queryName) this.agHelper.RenameQuery(queryName);
|
2022-07-29 08:48:25 +00:00
|
|
|
}
|
2022-08-24 14:23:41 +00:00
|
|
|
|
2022-09-09 15:59:47 +00:00
|
|
|
public UpdateGraphqlQueryAndVariable(options?: {
|
|
|
|
|
query?: string;
|
|
|
|
|
variable?: string;
|
|
|
|
|
}) {
|
|
|
|
|
if (options?.query) {
|
2023-05-11 05:26:03 +00:00
|
|
|
this.agHelper.UpdateCodeInput(this._graphqlQueryEditor, options.query);
|
2022-09-09 15:59:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (options?.variable) {
|
2023-05-11 05:26:03 +00:00
|
|
|
this.agHelper.UpdateCodeInput(
|
|
|
|
|
this._graphqlVariableEditor,
|
|
|
|
|
options.variable as string,
|
|
|
|
|
);
|
2022-09-09 15:59:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.agHelper.Sleep();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public UpdateGraphqlPaginationParams(options: {
|
|
|
|
|
limit?: {
|
|
|
|
|
variable: string;
|
|
|
|
|
value: any;
|
|
|
|
|
};
|
|
|
|
|
offset?: {
|
|
|
|
|
variable: string;
|
|
|
|
|
value: any;
|
|
|
|
|
};
|
|
|
|
|
}) {
|
|
|
|
|
if (options.limit) {
|
2023-05-29 05:40:41 +00:00
|
|
|
// Select Limit variable from dropdown
|
2022-09-09 15:59:47 +00:00
|
|
|
cy.get(this._graphqlPagination._limitVariable).click({
|
|
|
|
|
force: true,
|
|
|
|
|
});
|
2023-05-19 18:37:06 +00:00
|
|
|
cy.get(".rc-select-item-option")
|
2022-09-09 15:59:47 +00:00
|
|
|
.contains(options.limit.variable)
|
|
|
|
|
.click({ force: true });
|
|
|
|
|
|
2023-05-29 05:40:41 +00:00
|
|
|
// Set the Limit value as 1
|
2022-09-09 15:59:47 +00:00
|
|
|
cy.get(this._graphqlPagination._limitValue)
|
|
|
|
|
.first()
|
|
|
|
|
.focus()
|
|
|
|
|
.type(options.limit.value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (options.offset) {
|
2023-05-29 05:40:41 +00:00
|
|
|
// Select Offset vaiable from dropdown
|
2022-09-09 15:59:47 +00:00
|
|
|
cy.get(this._graphqlPagination._offsetVariable).click({
|
|
|
|
|
force: true,
|
|
|
|
|
});
|
2023-05-19 18:37:06 +00:00
|
|
|
cy.get(".rc-select-item-option")
|
|
|
|
|
.eq(2)
|
2022-09-09 15:59:47 +00:00
|
|
|
.contains(options.offset.variable)
|
|
|
|
|
.click({ force: true });
|
|
|
|
|
|
2023-05-29 05:40:41 +00:00
|
|
|
// Set the Limit value as 1
|
2022-09-09 15:59:47 +00:00
|
|
|
cy.get(this._graphqlPagination._offsetValue)
|
|
|
|
|
.first()
|
|
|
|
|
.focus()
|
|
|
|
|
.type(options.offset.value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.agHelper.Sleep();
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-10 13:55:06 +00:00
|
|
|
public SetQueryTimeout(
|
|
|
|
|
queryTimeout = 20000,
|
|
|
|
|
action: "QUERY" | "API" = "QUERY",
|
|
|
|
|
) {
|
2024-12-03 03:51:43 +00:00
|
|
|
// open the settings
|
|
|
|
|
this.pluginActionForm.toolbar.toggleSettings();
|
2022-08-24 14:23:41 +00:00
|
|
|
cy.xpath(this._queryTimeout)
|
|
|
|
|
.clear()
|
|
|
|
|
.type(queryTimeout.toString(), { delay: 0 }); //Delay 0 to work like paste!
|
|
|
|
|
this.agHelper.AssertAutoSave();
|
2024-12-03 03:51:43 +00:00
|
|
|
// close the settings
|
|
|
|
|
this.pluginActionForm.toolbar.toggleSettings();
|
2022-08-24 14:23:41 +00:00
|
|
|
}
|
2022-11-25 05:05:37 +00:00
|
|
|
|
|
|
|
|
//Update with new password in the datasource conf page
|
2023-02-02 07:59:24 +00:00
|
|
|
public UpdatePassword(newPassword: string) {
|
2022-11-25 05:05:37 +00:00
|
|
|
cy.get(this._password).type(newPassword);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//Fetch schema from server and validate UI for the updates
|
2023-02-02 07:59:24 +00:00
|
|
|
public VerifySchema(
|
2022-12-13 11:46:56 +00:00
|
|
|
dataSourceName: string,
|
|
|
|
|
schema: string,
|
|
|
|
|
isUpdate = false,
|
|
|
|
|
) {
|
2022-11-30 05:59:45 +00:00
|
|
|
if (isUpdate) {
|
2022-12-30 10:23:24 +00:00
|
|
|
this.UpdateDatasource();
|
2022-11-30 05:59:45 +00:00
|
|
|
} else {
|
|
|
|
|
this.SaveDatasource();
|
|
|
|
|
}
|
2023-11-15 02:31:12 +00:00
|
|
|
this.selectTabOnDatasourcePage("View data");
|
2023-07-25 12:27:16 +00:00
|
|
|
cy.wait("@getDatasourceStructure").then(() => {
|
2023-11-15 02:31:12 +00:00
|
|
|
cy.get(this._dsSchemaContainer).contains(schema);
|
2022-11-25 05:05:37 +00:00
|
|
|
});
|
|
|
|
|
}
|
2022-11-30 05:59:45 +00:00
|
|
|
|
2023-07-12 06:42:16 +00:00
|
|
|
public VerifyTableSchemaOnQueryEditor(schema: string) {
|
2023-11-15 02:31:12 +00:00
|
|
|
this.agHelper.AssertElementVisibility(this._dsVirtuosoElementTable(schema));
|
2023-07-12 06:42:16 +00:00
|
|
|
}
|
|
|
|
|
|
2023-07-24 06:48:20 +00:00
|
|
|
public VerifySchemaAbsenceInQueryEditor() {
|
|
|
|
|
this.agHelper.AssertElementAbsence(this._datasourceStructureHeader);
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-12 06:42:16 +00:00
|
|
|
public VerifyColumnSchemaOnQueryEditor(schema: string, index = 0) {
|
|
|
|
|
this.agHelper
|
2023-11-13 07:08:04 +00:00
|
|
|
.GetElement(this._datasourceSchemaColumn)
|
2023-07-12 06:42:16 +00:00
|
|
|
.eq(index)
|
|
|
|
|
.contains(schema);
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-24 12:09:46 +00:00
|
|
|
public RefreshDatasourceSchema() {
|
|
|
|
|
this.agHelper.GetNClick(this._datasourceSchemaRefreshBtn);
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-12 06:42:16 +00:00
|
|
|
public FilterAndVerifyDatasourceSchemaBySearch(
|
|
|
|
|
search: string,
|
2023-09-06 08:33:54 +00:00
|
|
|
expectedTableName = search,
|
2023-07-12 06:42:16 +00:00
|
|
|
) {
|
2023-08-04 03:46:59 +00:00
|
|
|
this.agHelper.Sleep(2500); //for query editor to load
|
2024-09-16 17:23:09 +00:00
|
|
|
this.agHelper.ClearNType(this._datasourceStructureSearchInput, search);
|
2023-10-06 12:05:19 +00:00
|
|
|
this.agHelper.Sleep(1000); //for search result to load
|
2023-09-06 08:33:54 +00:00
|
|
|
this.VerifyTableSchemaOnQueryEditor(expectedTableName);
|
2023-07-12 06:42:16 +00:00
|
|
|
}
|
|
|
|
|
|
2023-11-15 02:31:12 +00:00
|
|
|
public createQueryWithDatasourceSchemaTemplate(
|
|
|
|
|
datasourceName: string,
|
|
|
|
|
tableName: string,
|
|
|
|
|
templateName: string,
|
|
|
|
|
) {
|
2023-12-05 05:50:36 +00:00
|
|
|
this.CreateQueryForDS(datasourceName);
|
2023-11-15 02:31:12 +00:00
|
|
|
this.AssertTableInVirtuosoList(datasourceName, tableName);
|
2024-02-08 07:55:23 +00:00
|
|
|
this.agHelper.GetNClick(this._dsVirtuosoElementTable(tableName));
|
|
|
|
|
cy.get(this._dsVirtuosoElementTable(tableName))
|
|
|
|
|
.find(this._entityTriggerElement)
|
|
|
|
|
.should("be.visible")
|
|
|
|
|
.click();
|
2023-11-15 02:31:12 +00:00
|
|
|
this.agHelper.GetNClick(
|
|
|
|
|
this.entityExplorer.locator._contextMenuItem(templateName),
|
|
|
|
|
0,
|
|
|
|
|
true,
|
|
|
|
|
);
|
|
|
|
|
this.agHelper.Sleep(500);
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-24 10:29:05 +00:00
|
|
|
public AssertDSDialogVisibility(isVisible = true) {
|
|
|
|
|
if (isVisible) {
|
2023-08-10 07:06:03 +00:00
|
|
|
this.agHelper.AssertElementVisibility(this._datasourceModalDoNotSave);
|
|
|
|
|
this.agHelper.AssertElementVisibility(this._datasourceModalSave);
|
2023-07-24 10:29:05 +00:00
|
|
|
} else {
|
|
|
|
|
this.agHelper.AssertElementAbsence(this._datasourceModalDoNotSave);
|
|
|
|
|
this.agHelper.AssertElementAbsence(this._datasourceModalSave);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public AssertDatasourceSaveModalVisibilityAndSave(save = true) {
|
|
|
|
|
this.AssertDSDialogVisibility();
|
2022-11-30 05:59:45 +00:00
|
|
|
if (save) {
|
|
|
|
|
this.agHelper.GetNClick(
|
2023-05-19 18:37:06 +00:00
|
|
|
this.locator._visibleTextSpan("Save"),
|
2022-11-30 05:59:45 +00:00
|
|
|
0,
|
2023-05-19 18:37:06 +00:00
|
|
|
true,
|
2022-11-30 05:59:45 +00:00
|
|
|
0,
|
|
|
|
|
);
|
2023-06-18 04:55:16 +00:00
|
|
|
this.assertHelper.AssertNetworkStatus("@saveDatasource", 201);
|
2022-11-30 05:59:45 +00:00
|
|
|
this.agHelper.AssertContains("datasource created");
|
|
|
|
|
} else
|
|
|
|
|
this.agHelper.GetNClick(
|
2023-05-19 18:37:06 +00:00
|
|
|
this.locator._visibleTextSpan("Don't save"),
|
2022-11-30 05:59:45 +00:00
|
|
|
0,
|
2023-05-19 18:37:06 +00:00
|
|
|
true,
|
2022-11-30 05:59:45 +00:00
|
|
|
0,
|
|
|
|
|
);
|
2023-11-23 10:16:13 +00:00
|
|
|
this.AssertDSDialogVisibility(false);
|
2022-11-30 05:59:45 +00:00
|
|
|
}
|
2022-12-22 08:30:49 +00:00
|
|
|
|
2023-07-24 10:29:05 +00:00
|
|
|
// this initiates saving via the back button.
|
|
|
|
|
public SaveDSFromDialog(save = true) {
|
2023-11-30 00:41:59 +00:00
|
|
|
AppSidebar.navigate(AppSidebarButton.Editor, true);
|
2023-07-24 10:29:05 +00:00
|
|
|
this.AssertDatasourceSaveModalVisibilityAndSave(save);
|
|
|
|
|
}
|
|
|
|
|
|
2022-12-30 10:23:24 +00:00
|
|
|
public getDSEntity(dSName: string) {
|
2022-12-22 08:30:49 +00:00
|
|
|
return `[data-guided-tour-id="explorer-entity-${dSName}"]`;
|
|
|
|
|
}
|
2022-12-30 10:23:24 +00:00
|
|
|
|
2023-08-18 05:18:35 +00:00
|
|
|
public FillAuthAPIUrl(environment = this.dataManager.defaultEnviorment) {
|
2023-08-21 07:49:28 +00:00
|
|
|
this.agHelper.TypeText(
|
|
|
|
|
this.locator._inputFieldByName("URL") + "//" + this.locator._inputField,
|
2023-08-18 05:18:35 +00:00
|
|
|
this.dataManager.dsValues[environment].authenticatedApiUrl,
|
2023-03-16 18:28:32 +00:00
|
|
|
);
|
2022-12-30 10:23:24 +00:00
|
|
|
}
|
|
|
|
|
|
2023-02-10 10:41:17 +00:00
|
|
|
public AssertCursorPositionForTextInput(
|
|
|
|
|
selector: string,
|
|
|
|
|
moveCursor: string,
|
|
|
|
|
typeText = "as",
|
|
|
|
|
cursorPosition = 0,
|
|
|
|
|
) {
|
2023-03-16 18:28:32 +00:00
|
|
|
this.agHelper
|
|
|
|
|
.GetElement(selector)
|
2023-02-10 10:41:17 +00:00
|
|
|
.type(moveCursor)
|
|
|
|
|
.type(typeText)
|
|
|
|
|
.should("have.prop", "selectionStart", cursorPosition);
|
|
|
|
|
}
|
|
|
|
|
|
2022-12-30 10:23:24 +00:00
|
|
|
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));
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-21 05:53:17 +00:00
|
|
|
public FillMongoDatasourceFormWithURI(
|
2023-08-18 05:18:35 +00:00
|
|
|
environment = this.dataManager.defaultEnviorment,
|
2023-07-21 05:53:17 +00:00
|
|
|
) {
|
2023-05-19 18:37:06 +00:00
|
|
|
this.ValidateNSelectDropdown(
|
|
|
|
|
"Use mongo connection string URI",
|
|
|
|
|
"No",
|
|
|
|
|
"Yes",
|
|
|
|
|
);
|
2024-04-30 07:45:11 +00:00
|
|
|
this.agHelper.ClearNType(
|
2023-05-19 18:37:06 +00:00
|
|
|
this.locator._inputFieldByName("Connection string URI") + "//input",
|
2023-08-18 05:18:35 +00:00
|
|
|
this.dataManager.mongo_uri(environment),
|
2022-12-30 10:23:24 +00:00
|
|
|
);
|
|
|
|
|
}
|
2023-03-10 11:39:06 +00:00
|
|
|
|
2023-07-21 05:53:17 +00:00
|
|
|
public CreateOAuthClient(
|
|
|
|
|
grantType: string,
|
2023-08-18 05:18:35 +00:00
|
|
|
environment = this.dataManager.defaultEnviorment,
|
2023-07-21 05:53:17 +00:00
|
|
|
) {
|
2023-03-10 11:39:06 +00:00
|
|
|
let clientId, clientSecret;
|
|
|
|
|
|
|
|
|
|
// Login to TED OAuth
|
|
|
|
|
let formData = new FormData();
|
2023-07-21 05:53:17 +00:00
|
|
|
formData.append(
|
|
|
|
|
"username",
|
2023-08-18 05:18:35 +00:00
|
|
|
this.dataManager.dsValues[environment].OAuth_Username,
|
2023-07-11 05:14:13 +00:00
|
|
|
);
|
2023-07-21 05:53:17 +00:00
|
|
|
cy.request(
|
|
|
|
|
"POST",
|
2023-08-18 05:18:35 +00:00
|
|
|
this.dataManager.dsValues[environment].OAuth_Host,
|
2023-07-21 05:53:17 +00:00
|
|
|
formData,
|
|
|
|
|
).then((response) => {
|
|
|
|
|
expect(response.status).to.equal(200);
|
|
|
|
|
});
|
2023-03-10 11:39:06 +00:00
|
|
|
|
|
|
|
|
// Create client
|
|
|
|
|
let clientData = new FormData();
|
|
|
|
|
clientData.append("client_name", "appsmith_cs_post");
|
|
|
|
|
clientData.append("client_uri", "http://localhost/");
|
|
|
|
|
clientData.append("scope", "profile");
|
2023-07-21 05:53:17 +00:00
|
|
|
clientData.append(
|
|
|
|
|
"redirect_uri",
|
2023-08-18 05:18:35 +00:00
|
|
|
this.dataManager.dsValues[environment].OAuth_RedirectUrl,
|
2023-07-21 05:53:17 +00:00
|
|
|
);
|
2023-03-10 11:39:06 +00:00
|
|
|
clientData.append("grant_type", grantType);
|
|
|
|
|
clientData.append("response_type", "code");
|
|
|
|
|
clientData.append("token_endpoint_auth_method", "client_secret_post");
|
2023-07-11 05:14:13 +00:00
|
|
|
cy.request(
|
|
|
|
|
"POST",
|
2023-08-18 05:18:35 +00:00
|
|
|
this.dataManager.dsValues[environment].OAuth_Host + "/create_client",
|
2023-07-11 05:14:13 +00:00
|
|
|
clientData,
|
|
|
|
|
).then((response) => {
|
|
|
|
|
expect(response.status).to.equal(200);
|
|
|
|
|
});
|
2023-03-10 11:39:06 +00:00
|
|
|
|
|
|
|
|
// Get Client Credentials
|
2023-08-18 05:18:35 +00:00
|
|
|
cy.request("GET", this.dataManager.dsValues[environment].OAuth_Host).then(
|
2023-07-21 05:53:17 +00:00
|
|
|
(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");
|
|
|
|
|
},
|
|
|
|
|
);
|
2023-03-10 11:39:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public CreateOAuthDatasource(
|
|
|
|
|
datasourceName: string,
|
|
|
|
|
grantType: "ClientCredentials" | "AuthCode",
|
|
|
|
|
clientId: string,
|
|
|
|
|
clientSecret: string,
|
|
|
|
|
) {
|
|
|
|
|
this.NavigateToDSCreateNew();
|
|
|
|
|
//Click on Authenticated API
|
2023-03-15 05:03:34 +00:00
|
|
|
this.agHelper.GetNClick(this._authApiDatasource, 0, true);
|
2023-03-10 11:39:06 +00:00
|
|
|
this.FillAPIOAuthForm(datasourceName, grantType, clientId, clientSecret);
|
|
|
|
|
|
|
|
|
|
// save datasource
|
|
|
|
|
this.agHelper.Sleep(500);
|
2023-09-12 06:18:58 +00:00
|
|
|
this.agHelper.GetNClick(this._saveDs);
|
2023-03-10 11:39:06 +00:00
|
|
|
|
|
|
|
|
//Accept consent
|
|
|
|
|
this.agHelper.GetNClick(this._consent);
|
|
|
|
|
this.agHelper.GetNClick(this._consentSubmit);
|
|
|
|
|
|
|
|
|
|
//Validate save
|
2023-06-18 04:55:16 +00:00
|
|
|
this.assertHelper.AssertNetworkStatus("@saveDatasource", 201);
|
2023-03-10 11:39:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public FillAPIOAuthForm(
|
|
|
|
|
dsName: string,
|
|
|
|
|
grantType: "ClientCredentials" | "AuthCode",
|
|
|
|
|
clientId: string,
|
|
|
|
|
clientSecret: string,
|
2023-08-18 05:18:35 +00:00
|
|
|
environment = this.dataManager.defaultEnviorment,
|
2023-03-10 11:39:06 +00:00
|
|
|
) {
|
2024-12-03 03:51:43 +00:00
|
|
|
if (dsName) this.agHelper.RenameDatasource(dsName);
|
2023-03-10 11:39:06 +00:00
|
|
|
// Fill Auth Form
|
2023-08-21 07:49:28 +00:00
|
|
|
this.agHelper.TypeText(
|
|
|
|
|
this.locator._inputFieldByName("URL") + "//" + this.locator._inputField,
|
2023-08-18 05:18:35 +00:00
|
|
|
this.dataManager.dsValues[environment].OAuth_ApiUrl,
|
2023-03-10 11:39:06 +00:00
|
|
|
);
|
|
|
|
|
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);
|
|
|
|
|
|
2023-08-21 07:49:28 +00:00
|
|
|
this.agHelper.TypeText(
|
|
|
|
|
this.locator._inputFieldByName("Access token URL") +
|
|
|
|
|
"//" +
|
|
|
|
|
this.locator._inputField,
|
2023-08-18 05:18:35 +00:00
|
|
|
this.dataManager.dsValues[environment].OAUth_AccessTokenUrl,
|
2023-03-10 11:39:06 +00:00
|
|
|
);
|
|
|
|
|
|
2023-08-21 07:49:28 +00:00
|
|
|
this.agHelper.TypeText(
|
|
|
|
|
this.locator._inputFieldByName("Client ID") +
|
|
|
|
|
"//" +
|
|
|
|
|
this.locator._inputField,
|
2023-03-10 11:39:06 +00:00
|
|
|
clientId,
|
|
|
|
|
);
|
2023-08-21 07:49:28 +00:00
|
|
|
this.agHelper.TypeText(
|
|
|
|
|
this.locator._inputFieldByName("Client secret") +
|
|
|
|
|
"//" +
|
|
|
|
|
this.locator._inputField,
|
2023-03-10 11:39:06 +00:00
|
|
|
clientSecret,
|
|
|
|
|
);
|
2023-08-21 07:49:28 +00:00
|
|
|
this.agHelper.TypeText(
|
|
|
|
|
this.locator._inputFieldByName("Scope(s)") +
|
|
|
|
|
"//" +
|
|
|
|
|
this.locator._inputField,
|
2023-03-10 11:39:06 +00:00
|
|
|
"profile",
|
|
|
|
|
);
|
2023-08-21 07:49:28 +00:00
|
|
|
this.agHelper.TypeText(
|
|
|
|
|
this.locator._inputFieldByName("Authorization URL") +
|
|
|
|
|
"//" +
|
|
|
|
|
this.locator._inputField,
|
2023-08-18 05:18:35 +00:00
|
|
|
this.dataManager.dsValues[environment].OAuth_AuthUrl,
|
2023-03-10 11:39:06 +00:00
|
|
|
);
|
|
|
|
|
}
|
2023-03-16 18:28:32 +00:00
|
|
|
|
2024-02-13 08:22:04 +00:00
|
|
|
public AssertBindDataVisible() {
|
|
|
|
|
cy.get(this._bindDataButton).should("be.visible");
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-08 07:42:48 +00:00
|
|
|
public AddSuggestedWidget(
|
|
|
|
|
widget: Widgets,
|
|
|
|
|
parentClass = this._addSuggestedAddNew,
|
|
|
|
|
force = false,
|
|
|
|
|
index = 0,
|
|
|
|
|
) {
|
2024-02-13 08:22:04 +00:00
|
|
|
cy.get(this._bindDataButton).should("be.visible").click({ force: true });
|
2023-03-16 18:28:32 +00:00
|
|
|
switch (widget) {
|
|
|
|
|
case Widgets.Dropdown:
|
2023-09-08 07:42:48 +00:00
|
|
|
this.agHelper.GetNClick(
|
|
|
|
|
this._suggestedWidget("SELECT_WIDGET", parentClass),
|
|
|
|
|
);
|
2023-08-10 07:06:03 +00:00
|
|
|
this.agHelper.AssertElementVisibility(
|
2023-03-16 18:28:32 +00:00
|
|
|
this.locator._widgetInCanvas(WIDGET.SELECT),
|
|
|
|
|
);
|
|
|
|
|
break;
|
|
|
|
|
case Widgets.Table:
|
2023-08-21 07:49:28 +00:00
|
|
|
this.agHelper.GetNClick(
|
2023-09-08 07:42:48 +00:00
|
|
|
this._suggestedWidget("TABLE_WIDGET_V2", parentClass),
|
2023-08-21 07:49:28 +00:00
|
|
|
index,
|
|
|
|
|
force,
|
|
|
|
|
);
|
2023-08-10 07:06:03 +00:00
|
|
|
this.agHelper.AssertElementVisibility(
|
2023-03-16 18:28:32 +00:00
|
|
|
this.locator._widgetInCanvas(WIDGET.TABLE),
|
|
|
|
|
);
|
|
|
|
|
break;
|
2024-01-31 05:32:38 +00:00
|
|
|
case Widgets.WDSTable:
|
|
|
|
|
this.agHelper.GetNClick(
|
|
|
|
|
this._suggestedWidget("TABLE_WIDGET_V2", parentClass),
|
|
|
|
|
index,
|
|
|
|
|
force,
|
|
|
|
|
);
|
|
|
|
|
this.agHelper.AssertElementVisibility(
|
2024-05-30 07:16:56 +00:00
|
|
|
anvilLocators.anvilWidgetTypeSelector(anvilLocators.WDSTABLE),
|
2024-01-31 05:32:38 +00:00
|
|
|
);
|
|
|
|
|
break;
|
2023-03-16 18:28:32 +00:00
|
|
|
case Widgets.Chart:
|
2023-09-08 07:42:48 +00:00
|
|
|
this.agHelper.GetNClick(
|
|
|
|
|
this._suggestedWidget("CHART_WIDGET", parentClass),
|
|
|
|
|
);
|
2023-08-10 07:06:03 +00:00
|
|
|
this.agHelper.AssertElementVisibility(
|
2023-03-16 18:28:32 +00:00
|
|
|
this.locator._widgetInCanvas(WIDGET.CHART),
|
|
|
|
|
);
|
|
|
|
|
break;
|
|
|
|
|
case Widgets.Text:
|
2023-09-08 07:42:48 +00:00
|
|
|
this.agHelper.GetNClick(
|
|
|
|
|
this._suggestedWidget("TEXT_WIDGET", parentClass),
|
|
|
|
|
);
|
2023-08-10 07:06:03 +00:00
|
|
|
this.agHelper.AssertElementVisibility(
|
2023-03-16 18:28:32 +00:00
|
|
|
this.locator._widgetInCanvas(WIDGET.TEXT),
|
|
|
|
|
);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-06-14 06:46:09 +00:00
|
|
|
|
|
|
|
|
public EnterJSContext({
|
|
|
|
|
fieldLabel,
|
|
|
|
|
fieldValue,
|
|
|
|
|
}: {
|
|
|
|
|
fieldValue: string;
|
|
|
|
|
fieldLabel: string;
|
|
|
|
|
}) {
|
2023-06-15 13:21:11 +00:00
|
|
|
this.agHelper.Sleep();
|
|
|
|
|
this.agHelper
|
2023-07-26 13:26:24 +00:00
|
|
|
.GetElement(this._getJSONswitchLocator(fieldLabel))
|
2023-06-15 13:21:11 +00:00
|
|
|
.invoke("attr", "data-selected")
|
|
|
|
|
.then(($state: any) => {
|
|
|
|
|
if (!$state.includes("true"))
|
|
|
|
|
this.agHelper.GetNClick(
|
2023-07-26 13:26:24 +00:00
|
|
|
this._getJSONswitchLocator(fieldLabel),
|
2023-06-15 13:21:11 +00:00
|
|
|
0,
|
|
|
|
|
true,
|
|
|
|
|
);
|
|
|
|
|
else this.agHelper.Sleep(200);
|
|
|
|
|
});
|
2023-06-14 06:46:09 +00:00
|
|
|
this.agHelper.EnterValue(fieldValue, {
|
|
|
|
|
propFieldName: "",
|
|
|
|
|
directInput: false,
|
|
|
|
|
inputFieldName: fieldLabel,
|
|
|
|
|
});
|
|
|
|
|
}
|
2023-06-21 17:37:21 +00:00
|
|
|
|
|
|
|
|
public StopNDeleteContainer(containerName: string) {
|
|
|
|
|
// Stop the container
|
|
|
|
|
cy.exec(`docker stop ${containerName}`).then((stopResult) => {
|
|
|
|
|
cy.log("Output from stopping container:" + stopResult.stdout);
|
|
|
|
|
cy.log("Error from stopping container:" + stopResult.stderr);
|
|
|
|
|
|
|
|
|
|
// Delete the container
|
|
|
|
|
cy.exec(`docker rm ${containerName}`).then((deleteResult) => {
|
|
|
|
|
cy.log("Output from deleting container:" + deleteResult.stdout);
|
|
|
|
|
cy.log("Error from deleting container:" + deleteResult.stderr);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public IsContainerReady(containerName: string) {
|
|
|
|
|
return cy
|
|
|
|
|
.exec(`docker inspect -f '{{.State.Status}}' ${containerName}`)
|
|
|
|
|
.then((result) => {
|
|
|
|
|
const containerStatus = result.stdout.trim();
|
|
|
|
|
return containerStatus === "running";
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public StartContainerNVerify(
|
|
|
|
|
containerType: "MsSql" | "Arango" | "Elasticsearch",
|
|
|
|
|
containerName: string,
|
2023-07-06 05:13:15 +00:00
|
|
|
sleepTime = 40000,
|
2023-06-21 17:37:21 +00:00
|
|
|
) {
|
|
|
|
|
let containerCommand = "";
|
|
|
|
|
switch (containerType) {
|
|
|
|
|
case "MsSql":
|
|
|
|
|
containerCommand = this.ContainerKVP(containerName).MsSql;
|
|
|
|
|
break;
|
|
|
|
|
case "Arango":
|
|
|
|
|
containerCommand = this.ContainerKVP(containerName).Arango;
|
|
|
|
|
break;
|
|
|
|
|
case "Elasticsearch":
|
|
|
|
|
containerCommand = this.ContainerKVP(containerName).Elasticsearch;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
cy.exec(containerCommand).then((result) => {
|
|
|
|
|
// Wait for the container to be ready
|
|
|
|
|
cy.waitUntil(() => this.IsContainerReady(containerName), {
|
|
|
|
|
interval: 5000,
|
|
|
|
|
timeout: 60000,
|
|
|
|
|
}).then((isReady) => {
|
|
|
|
|
if (isReady) {
|
|
|
|
|
cy.log("Run id of started container is:" + result.stdout);
|
2023-06-22 12:05:59 +00:00
|
|
|
this.agHelper.Sleep(sleepTime); //allow some time for container to settle start for CI
|
2023-06-21 17:37:21 +00:00
|
|
|
} else
|
|
|
|
|
cy.log(
|
|
|
|
|
`Error from ${containerName} container start action:` +
|
|
|
|
|
result.stderr,
|
|
|
|
|
); // Container did not start properly within the timeout
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
}
|
2023-07-26 13:26:24 +00:00
|
|
|
|
|
|
|
|
public EnterSortByValues(sortBy: string, option: string, index = 0) {
|
|
|
|
|
this.agHelper
|
|
|
|
|
.GetElement(this._jsModeSortingControl)
|
|
|
|
|
.eq(0)
|
|
|
|
|
.children()
|
|
|
|
|
.eq(index)
|
|
|
|
|
.then((ele) => {
|
|
|
|
|
cy.wrap(ele)
|
|
|
|
|
.children()
|
|
|
|
|
.eq(0)
|
|
|
|
|
.find("textarea")
|
|
|
|
|
.type(sortBy, { force: true });
|
|
|
|
|
cy.wrap(ele).children().eq(1).find("input").click();
|
|
|
|
|
});
|
|
|
|
|
this.agHelper.GetNClickByContains(this._dropdownOption, option);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public ClearSortByOption(index = 0) {
|
|
|
|
|
this.agHelper.Sleep(500);
|
|
|
|
|
this.agHelper
|
|
|
|
|
.GetElement(this._jsModeSortingControl)
|
|
|
|
|
.eq(0)
|
|
|
|
|
.children()
|
|
|
|
|
.eq(index)
|
|
|
|
|
.find(`button[data-testid='t--sorting-delete-[${index}]']`)
|
|
|
|
|
.click({ force: true });
|
|
|
|
|
this.agHelper.Sleep(500);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public AddNewSortByParameter() {
|
|
|
|
|
this.agHelper
|
|
|
|
|
.GetElement(this._jsModeSortingControl)
|
|
|
|
|
.find("button[data-testid='t--sorting-add-field']")
|
|
|
|
|
.click({ force: true });
|
|
|
|
|
}
|
2023-08-01 11:12:44 +00:00
|
|
|
|
|
|
|
|
public AddQueryFromGlobalSearch(datasourceName: string) {
|
|
|
|
|
this.agHelper.GetNClick(this._globalSearchTrigger);
|
|
|
|
|
this.agHelper.Sleep(500);
|
|
|
|
|
this.agHelper.TypeText(this._globalSearchInput, datasourceName);
|
|
|
|
|
this.agHelper.Sleep(500);
|
|
|
|
|
this.agHelper.GetNClickByContains(
|
|
|
|
|
this._globalSearchOptions,
|
2023-08-01 17:13:14 +00:00
|
|
|
new RegExp("^" + datasourceName + "$"),
|
2023-08-01 11:12:44 +00:00
|
|
|
);
|
|
|
|
|
this.agHelper.WaitUntilEleAppear(this._createQuery);
|
2023-12-08 05:37:23 +00:00
|
|
|
this.CreateQueryAfterDSSaved();
|
2023-08-01 11:12:44 +00:00
|
|
|
}
|
2023-08-08 09:14:46 +00:00
|
|
|
|
|
|
|
|
public AssertDataSourceInfo(info: string[]) {
|
|
|
|
|
info.forEach(($infs) => {
|
2023-08-10 07:06:03 +00:00
|
|
|
this.agHelper.AssertElementVisibility(
|
|
|
|
|
this.locator._visibleTextDiv($infs),
|
|
|
|
|
);
|
2023-08-08 09:14:46 +00:00
|
|
|
});
|
|
|
|
|
}
|
2023-09-26 07:34:41 +00:00
|
|
|
|
2024-01-25 13:41:48 +00:00
|
|
|
public GeneratePostgresCRUDPage(dbName: string) {
|
|
|
|
|
PageList.AddNewPage("Generate page with data");
|
|
|
|
|
this.agHelper.GetNClick(this._selectDatasourceDropdown);
|
|
|
|
|
this.agHelper.GetNClickByContains(
|
|
|
|
|
this._dropdownOption,
|
|
|
|
|
"Connect new datasource",
|
|
|
|
|
);
|
|
|
|
|
this.CreateDataSource("Postgres", false);
|
|
|
|
|
this.assertHelper.AssertNetworkStatus("@getDatasourceStructure");
|
|
|
|
|
this.agHelper.GetNClick(this._selectTableDropdown, 0, true);
|
|
|
|
|
this.agHelper.GetNClickByContains(this._dropdownOption, dbName);
|
|
|
|
|
this.agHelper.GetNClick(this._generatePageBtn);
|
|
|
|
|
this.assertHelper.AssertNetworkStatus("@replaceLayoutWithCRUDPage", 201);
|
|
|
|
|
this.agHelper.AssertContains("Successfully generated a page");
|
|
|
|
|
this.assertHelper.AssertNetworkStatus("@getActions", 200);
|
|
|
|
|
this.assertHelper.AssertNetworkStatus("@postExecute", 200);
|
|
|
|
|
this.agHelper.GetNClick(this._visibleTextSpan("Got it"));
|
|
|
|
|
this.assertHelper.AssertNetworkStatus("@updateLayout", 200);
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-26 07:34:41 +00:00
|
|
|
public AssertTableInVirtuosoList(
|
|
|
|
|
dsName: string,
|
|
|
|
|
targetTableName: string,
|
|
|
|
|
presence = true,
|
|
|
|
|
) {
|
|
|
|
|
const ds_entity_name = dsName.replace(/\s/g, "_");
|
2023-11-15 02:31:12 +00:00
|
|
|
cy.intercept("GET", "/api/v1/datasources/*/structure?ignoreCache=*").as(
|
|
|
|
|
`getDatasourceStructureUpdated_${ds_entity_name}`,
|
|
|
|
|
);
|
2024-12-09 12:42:09 +00:00
|
|
|
cy.get("[data-testid=t--tab-DATASOURCE_TAB]")
|
|
|
|
|
.first()
|
|
|
|
|
.click({ force: true });
|
2023-11-15 02:31:12 +00:00
|
|
|
this.RefreshDatasourceSchema();
|
|
|
|
|
this.assertHelper
|
|
|
|
|
.WaitForNetworkCall(`@getDatasourceStructureUpdated_${ds_entity_name}`)
|
|
|
|
|
.then(async (response) => {
|
|
|
|
|
const tables: any[] = response?.body.data?.tables || [];
|
|
|
|
|
const indexOfTable = tables.findIndex(
|
|
|
|
|
(table) => table.name === targetTableName,
|
2023-09-26 07:34:41 +00:00
|
|
|
);
|
2023-11-15 02:31:12 +00:00
|
|
|
if (presence) {
|
|
|
|
|
this.agHelper.Sleep();
|
|
|
|
|
this.agHelper
|
|
|
|
|
.GetNClick(this._dsVirtuosoElement)
|
|
|
|
|
.then((parentElement) => {
|
|
|
|
|
const heightOfParentElement = parentElement.outerHeight() || 0;
|
|
|
|
|
|
|
|
|
|
// Every element (tables in this scenario) in the virtual list has equal heights. Assumption: Every table element accordion is collapsed by default.
|
|
|
|
|
const containerElement = parentElement.find(this._dsVirtuosoList);
|
|
|
|
|
const elementHeight = parseInt(
|
|
|
|
|
containerElement.children().first().attr("data-known-size") ||
|
|
|
|
|
"",
|
|
|
|
|
10,
|
|
|
|
|
);
|
|
|
|
|
// Total height of the parent container holding the tables in the dom normally without virtualization rendering
|
|
|
|
|
const totalScroll = tables.length * elementHeight;
|
|
|
|
|
if (heightOfParentElement < totalScroll) {
|
|
|
|
|
// Index of the table present in the array of tables which will determine the presence of element inside the parent container
|
|
|
|
|
let offset = indexOfTable * elementHeight;
|
|
|
|
|
const scrollPercent = Math.max(
|
|
|
|
|
(offset / (totalScroll || 1)) * 100,
|
|
|
|
|
0,
|
|
|
|
|
);
|
|
|
|
|
if (scrollPercent > 0) {
|
|
|
|
|
this.agHelper.ScrollToXY(
|
|
|
|
|
this._dsVirtuosoElement,
|
|
|
|
|
0,
|
|
|
|
|
`${scrollPercent}%`,
|
2023-10-17 14:56:24 +00:00
|
|
|
);
|
2023-11-15 02:31:12 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// To close any template pop up, click on the body
|
|
|
|
|
cy.get(this.locator._body).click({ force: true });
|
|
|
|
|
this.agHelper.AssertElementVisibility(
|
|
|
|
|
this._dsVirtuosoElementTable(targetTableName),
|
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
this.agHelper.AssertElementAbsence(
|
|
|
|
|
this._dsVirtuosoElementTable(targetTableName),
|
|
|
|
|
);
|
|
|
|
|
expect(indexOfTable).to.equal(-1);
|
|
|
|
|
}
|
|
|
|
|
});
|
2023-09-26 07:34:41 +00:00
|
|
|
}
|
2023-10-06 12:05:19 +00:00
|
|
|
|
|
|
|
|
public selectTabOnDatasourcePage(tab: "View data" | "Configurations") {
|
|
|
|
|
this.agHelper.GetNClick(this._dsPageTabListItem(tab));
|
|
|
|
|
}
|
2023-11-15 02:31:12 +00:00
|
|
|
|
|
|
|
|
public getDatasourceListItemDescription(name: string) {
|
|
|
|
|
return cy
|
|
|
|
|
.get(datasource.datasourceCard)
|
|
|
|
|
.contains(name)
|
|
|
|
|
.parents(datasource.datasourceCard)
|
|
|
|
|
.find(".ads-v2-listitem__bdesc")
|
|
|
|
|
.invoke("text");
|
|
|
|
|
}
|
2024-01-16 08:30:51 +00:00
|
|
|
|
|
|
|
|
public SelectTableFromPreviewSchemaList(targetTableName: string) {
|
|
|
|
|
this.agHelper.GetNClick(
|
|
|
|
|
this._dsVirtuosoElementTable(targetTableName),
|
|
|
|
|
0,
|
|
|
|
|
false,
|
|
|
|
|
1000,
|
|
|
|
|
);
|
|
|
|
|
}
|
2024-02-02 09:56:26 +00:00
|
|
|
|
|
|
|
|
private IsTemplateMenuTriggerForSchemaTableVisible(index: number = 0) {
|
|
|
|
|
this.agHelper
|
|
|
|
|
.GetElement(`${this._dsSchemaContainer} ${this._dsSchemaEntityItem}`)
|
|
|
|
|
.eq(index)
|
|
|
|
|
.find(this._entityTriggerElement)
|
|
|
|
|
.should("be.visible");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public ClickTemplateMenuForSchemaTable(index: number = 0) {
|
|
|
|
|
this.agHelper
|
|
|
|
|
.GetElement(`${this._dsSchemaContainer} ${this._dsSchemaEntityItem}`)
|
|
|
|
|
.eq(index)
|
|
|
|
|
.realHover();
|
|
|
|
|
this.IsTemplateMenuTriggerForSchemaTableVisible(index);
|
|
|
|
|
this.agHelper
|
|
|
|
|
.GetElement(`${this._dsSchemaContainer} ${this._dsSchemaEntityItem}`)
|
|
|
|
|
.eq(index)
|
|
|
|
|
.find(this._entityTriggerElement)
|
|
|
|
|
.click();
|
|
|
|
|
this.IsTemplateMenuTriggerForSchemaTableVisible(index);
|
|
|
|
|
}
|
2022-05-18 10:39:42 +00:00
|
|
|
}
|