|
|
@ -70,4 +70,3 @@ SSO_DISABLE_SIGNUPS=
|
|||
|
||||
#ONBOARDING
|
||||
ENABLE_ONBOARDING_QUESTIONS_FOR_ALL_SIGN_UPS=
|
||||
ENABLE_TOOLJET_DB=
|
||||
|
|
|
|||
13
.github/workflows/packer-build.yml
vendored
|
|
@ -4,6 +4,12 @@ on:
|
|||
release:
|
||||
types: [published]
|
||||
|
||||
# Allows you to run this workflow manually from the Actions tab
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version:
|
||||
description: "RELEASE_VERSION"
|
||||
|
||||
jobs:
|
||||
packer:
|
||||
runs-on: ubuntu-latest
|
||||
|
|
@ -13,7 +19,12 @@ jobs:
|
|||
- name: Checkout Repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Set env
|
||||
- name: Setting tag
|
||||
if: "${{ github.event.inputs.version != '' }}"
|
||||
run: echo "RELEASE_VERSION=${{ github.event.inputs.version }}" >> $GITHUB_ENV
|
||||
|
||||
- name: Set evn
|
||||
if: "${{ github.event.release }}"
|
||||
run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV
|
||||
|
||||
- name: Configure AWS Credentials
|
||||
|
|
|
|||
2
.version
|
|
@ -1 +1 @@
|
|||
2.0.4
|
||||
2.1.0
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ You can use ToolJet cloud for a fully managed solution. If you want to self-host
|
|||
|
||||
|
||||
## Community support
|
||||
For general help using ToolJet, please refer to the official [documentation](https://docs.tooljet.com/docs/intro/). For additional help, you can use one of these channels to ask a question:
|
||||
For general help using ToolJet, please refer to the official [documentation](https://docs.tooljet.com/docs/). For additional help, you can use one of these channels to ask a question:
|
||||
|
||||
- [Slack](https://join.slack.com/t/tooljet/shared_invite/zt-r2neyfcw-KD1COL6t2kgVTlTtAV5rtg) - Discussions with the community and the team.
|
||||
- [GitHub](https://github.com/ToolJet/ToolJet/issues) - For bug reports and feature requests.
|
||||
|
|
|
|||
3
cypress-tests/.gitignore
vendored
|
|
@ -1 +1,2 @@
|
|||
/node_modules
|
||||
/node_modules
|
||||
/cypress.env.json
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
const { defineConfig } = require("cypress");
|
||||
const { rmdir } = require("fs");
|
||||
const pg = require('pg');
|
||||
const pg = require("pg");
|
||||
|
||||
module.exports = defineConfig({
|
||||
execTimeout: 1800000,
|
||||
|
|
@ -12,21 +12,7 @@ module.exports = defineConfig({
|
|||
viewportHeight: 960,
|
||||
chromeWebSecurity: false,
|
||||
trashAssetsBeforeRuns: true,
|
||||
env: {
|
||||
pg_host: "",
|
||||
pg_user: "",
|
||||
pg_password: "",
|
||||
sso_password: "",
|
||||
git_user: "",
|
||||
google_user: "",
|
||||
},
|
||||
db: {
|
||||
user: "postgres",
|
||||
host: "localhost",
|
||||
database: "tooljet_development",
|
||||
password: "postgres",
|
||||
port: "5432",
|
||||
},
|
||||
|
||||
e2e: {
|
||||
setupNodeEvents(on, config) {
|
||||
on("task", {
|
||||
|
|
@ -44,16 +30,21 @@ module.exports = defineConfig({
|
|||
});
|
||||
|
||||
on("task", {
|
||||
UpdateId({dbconfig,sql}){
|
||||
UpdateId({ dbconfig, sql }) {
|
||||
const client = new pg.Pool(dbconfig);
|
||||
return client.query(sql);
|
||||
}
|
||||
})
|
||||
},
|
||||
});
|
||||
|
||||
return require("./cypress/plugins/index.js")(on, config);
|
||||
},
|
||||
experimentalRunAllSpecs: true,
|
||||
experimentalModfyObstructiveThirdPartyCode: true,
|
||||
experimentalRunAllSpecs: true,
|
||||
baseUrl: "http://localhost:8082",
|
||||
specPattern: "cypress/e2e/**/*.cy.js",
|
||||
numTestsKeptInMemory: 25,
|
||||
redirectionLimit: 10,
|
||||
experimentalRunAllSpecs: true,
|
||||
},
|
||||
});
|
||||
|
|
|
|||
49
cypress-tests/cypress.env.example
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
{
|
||||
"sso_password": "",
|
||||
"git_user": "",
|
||||
"google_user": "",
|
||||
|
||||
"pg_host": "",
|
||||
"pg_user": "",
|
||||
"pg_password": "",
|
||||
|
||||
"elasticsearch_host": "",
|
||||
"elasticsearch_user": "",
|
||||
"elasticsearch_password": "",
|
||||
|
||||
"dynamodb_access_key": "",
|
||||
"dynamodb_secret_key": "",
|
||||
|
||||
"smtp_host": "",
|
||||
"smtp_port": "",
|
||||
"smtp_user": "",
|
||||
"smtp_password": "",
|
||||
|
||||
"redis_host": "",
|
||||
"redis_port": "",
|
||||
"redis_password": "",
|
||||
|
||||
"mongodb_connString": "",
|
||||
"mongodb_host": "",
|
||||
"mongodb_user": "",
|
||||
"mongo_password": "",
|
||||
|
||||
"bigquery_pvt_key": {},
|
||||
|
||||
"firestore_pvt_key": {},
|
||||
|
||||
"mysql_host": "",
|
||||
"mysql_user": "",
|
||||
"mysql_password": "",
|
||||
|
||||
"aws_access": "",
|
||||
"aws_secret": "",
|
||||
|
||||
"app_db": {
|
||||
"user": "postgres",
|
||||
"host": "localhost",
|
||||
"database": "tooljet_development",
|
||||
"password": "postgres",
|
||||
"port": "5432"
|
||||
}
|
||||
}
|
||||
9
cypress-tests/cypress/constants/selectors/awss3.js
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
export const s3Selector = {
|
||||
awsDatasource: '[data-cy="data-source-aws s3"]',
|
||||
accessKeyLabel: '[data-cy="label-access-key"]',
|
||||
secretKeyLabel: '[data-cy="label-secret-key"]',
|
||||
regionLabel: '[data-cy="label-region"]',
|
||||
customEndpointLabel: '[data-cy="label-custom-endpoint"]',
|
||||
customEndpointInput: '[data-cy="undefined-text-field"]',
|
||||
dataSourceNameInput: '[data-cy="data-source-name-input-filed"]',
|
||||
};
|
||||
|
|
@ -15,8 +15,10 @@ export const commonSelectors = {
|
|||
skipButton: ".driver-close-btn",
|
||||
skipInstallationModal: "[data-cy=skip-button]",
|
||||
homePageLogo: "[data-cy=home-page-logo]",
|
||||
pageLogo: "[data-cy=page-logo]",
|
||||
workEmailLabel: '[data-cy="work-email-label"]',
|
||||
workEmailInputField: "[data-cy=work-email-input]",
|
||||
emailInputError: '[data-cy="email-error-message"]',
|
||||
passwordLabel: '[data-cy="password-label"]',
|
||||
forgotPasswordLink: '[data-cy="forgot-password-link"]',
|
||||
passwordInputField: "[data-cy=password-input-field]",
|
||||
|
|
@ -64,6 +66,7 @@ export const commonSelectors = {
|
|||
createWorkspaceButton: '[data-cy="create-workspace-button"]',
|
||||
workspaceLoginUrl: "[data-cy=workspace-login-url]",
|
||||
workspaceName: '[data-cy="workspace-name"]',
|
||||
signInHeader: '[data-cy="sign-in-header"]',
|
||||
signInSubHeader: '[data-cy="sign-in-sub-header"]',
|
||||
createAnAccountLink: '[data-cy="create-an-account-link"]',
|
||||
SignUpSectionHeader: '[data-cy="signup-section-header"]',
|
||||
|
|
@ -162,8 +165,8 @@ export const commonWidgetSelector = {
|
|||
return `[data-cy="${widgetName.toLowerCase()}-invalid-feedback"]`;
|
||||
},
|
||||
|
||||
buttonCloseEditorSideBar: "[data-rb-event-key='close-inpector-light']",
|
||||
buttonStylesEditorSideBar: "[data-rb-event-key='styles']",
|
||||
buttonCloseEditorSideBar: "[data-cy='inspector-close-icon']",
|
||||
buttonStylesEditorSideBar: "[data-cy='sidebar-option-styles']",
|
||||
WidgetNameInputField: "[data-cy=edit-widget-name]",
|
||||
|
||||
tooltipInputField: "[data-cy='tooltip-input-field']",
|
||||
|
|
@ -182,8 +185,10 @@ export const commonWidgetSelector = {
|
|||
'[data-cy="action-options-action-selection-field"]',
|
||||
componentTextInput: '[data-cy="action-options-text-input-field"]',
|
||||
changeLayoutButton: "[data-cy= 'change-layout-button']",
|
||||
changeLayoutToMobileButton: '[data-cy="button-change-layout-to-desktop"]',
|
||||
changeLayoutToDesktopButton: '[data-cy="button-change-layout-to-mobile"]',
|
||||
|
||||
sidebarinspector: "[data-cy='left-sidebar-inspector-button']",
|
||||
sidebarinspector: "[data-cy='left-sidebar-inspect-button']",
|
||||
inspectorNodeComponents: "[data-cy='inspector-node-components']> .node-key",
|
||||
nodeComponentValue: "[data-cy='inspector-node-value']> .mx-2",
|
||||
nodeComponentValues: "[data-cy='inspector-node-values']> .node-key",
|
||||
|
|
@ -196,4 +201,4 @@ export const commonWidgetSelector = {
|
|||
boxShadowColorPicker: "[data-cy='box-shadow-picker']",
|
||||
textInputWidget: '[data-cy="draggable-widget-textinput1"]',
|
||||
previewButton: `[data-cy="preview-link-button"]`,
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,15 +0,0 @@
|
|||
export const loginSelectors = {
|
||||
logo: "[data-cy=login-page-logo]",
|
||||
cardTitle: "[data-cy=login-page-header]",
|
||||
emailLabel: "[data-cy=email-label]",
|
||||
emailField: "[data-cy=email-text-field]",
|
||||
passwordLabel: "[data-cy=password-label]",
|
||||
forgotPassword: "[data-cy=forgot-password-link]",
|
||||
passwordField: "[data-cy=password-text-field]",
|
||||
checkBox: "[data-cy=checkbox-input]",
|
||||
showPassword: "[data-cy=show-password-label]",
|
||||
signInButton: "[data-cy=login-button]",
|
||||
signUpText: "[data-cy=sign-up-message]",
|
||||
signUpLink: "[data-cy=sign-up-link]",
|
||||
homePage: "[data-cy=home-page-logo]",
|
||||
};
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
export const postgreSqlSelector = {
|
||||
leftSidebarDatasourceButton: "[data-cy='left-sidebar-sources-button']",
|
||||
leftSidebarDatasourceButton: "[data-cy='left-sidebar-database-button']",
|
||||
labelDataSources: "[data-cy='label-datasources']",
|
||||
addDatasourceLink: "[data-cy='add-datasource-link']",
|
||||
|
||||
|
|
|
|||
18
cypress-tests/cypress/constants/texts/awss3.js
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
export const s3Text = {
|
||||
awsS3: "AWS S3",
|
||||
accessKey: "Access key",
|
||||
secretKey: "Secret keyEncrypted",
|
||||
region: "Region",
|
||||
customEndpoint: "Custom Endpoint",
|
||||
alertRegionIsMissing: "Region is missing",
|
||||
cypressAwsS3: "cypress-aws-s3",
|
||||
placeholderEnterAccessKey: "Enter access key",
|
||||
placeholderEnterSecretKey: "Enter secret key",
|
||||
labelRegion: "Region",
|
||||
region: "N. california",
|
||||
alertInvalidUrl: "Invalid URL:",
|
||||
accessKeyError:
|
||||
"The AWS Access Key Id you provided does not exist in our records.",
|
||||
sinatureError:
|
||||
"The request signature we calculated does not match the signature you provided. Check your key and signing method.",
|
||||
};
|
||||
7
cypress-tests/cypress/constants/texts/bigquery.js
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
export const bigqueryText = {
|
||||
bigQuery: "BigQuery",
|
||||
cypressBigQuery: "cypress-bigquery",
|
||||
errorInvalidEmailId:
|
||||
"The incoming JSON object does not contain a client_email field",
|
||||
placehlderPrivateKey: "Enter JSON private key for service account",
|
||||
};
|
||||
|
|
@ -12,7 +12,7 @@ export const path = {
|
|||
};
|
||||
|
||||
export const commonText = {
|
||||
autoSave: "All changes are saved",
|
||||
autoSave: "Saved changes",
|
||||
email: "dev@tooljet.io",
|
||||
password: "password",
|
||||
loginErrorToast: "Invalid email or password",
|
||||
|
|
@ -51,9 +51,11 @@ export const commonText = {
|
|||
"Are you sure you want to delete the folder? Apps within the folder will not be deleted.",
|
||||
closeButton: "modal close",
|
||||
workEmailLabel: "Email",
|
||||
emailInputError: "Invalid Email",
|
||||
passwordLabel: "Password",
|
||||
forgotPasswordLink: "Forgot?",
|
||||
loginButton: " Login",
|
||||
signInHeader: "Sign in",
|
||||
signInSubHeader: "New to ToolJet?Create an account",
|
||||
SignUpSectionHeader: "Join ToolJet",
|
||||
signInRedirectText: "Already have an account?",
|
||||
|
|
@ -139,4 +141,4 @@ export const widgetValue = (widgetName) => {
|
|||
|
||||
export const customValidation = (name, message) => {
|
||||
return ["{{", `components.${name}.value ? true : '${message}'}}`];
|
||||
};
|
||||
};
|
||||
|
|
|
|||
14
cypress-tests/cypress/constants/texts/dynamodb.js
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
export const dynamoDbText = {
|
||||
dynamoDb: "DynamoDB",
|
||||
cypressDynamoDb: "cypress-dynamodb",
|
||||
region: "Region",
|
||||
accessKey: "Access key",
|
||||
placeHolderAccessKey: "Enter access key",
|
||||
secretKey: "Secret key",
|
||||
placeholderSecretKey: "Enter secret key",
|
||||
|
||||
errorMissingRegion: "Missing region in config",
|
||||
errorInvalidToken: "The security token included in the request is invalid.",
|
||||
errorSignatureMissmatch:
|
||||
"The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.",
|
||||
};
|
||||
7
cypress-tests/cypress/constants/texts/elasticsearch.js
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
export const elasticsearchText = {
|
||||
elasticSearch: "Elasticsearch",
|
||||
cypressElasticsearch: "cypress-elasticsearch",
|
||||
|
||||
errorConnectionRefused: "connect ECONNREFUSED 127.0.0.1:9200",
|
||||
errorGetAddrInfoNotFound: "getaddrinfo ENOTFOUND elasticsearch_host",
|
||||
};
|
||||
10
cypress-tests/cypress/constants/texts/firestore.js
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
export const firestoreText = {
|
||||
firestore: "Firestore",
|
||||
cypressFirestore: "cypress-firestore",
|
||||
labelPrivateKey: "Private keyEncrypted",
|
||||
privateKey: "Private key",
|
||||
placeholderPrivateKey: "Enter private key",
|
||||
|
||||
errorGcpKeyCouldNotBeParsed:
|
||||
"GCP key could not be parsed as a valid JSON object",
|
||||
};
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
export const loginTexts = {
|
||||
cardTitle: "Login to your account",
|
||||
emailLabel: "Email address",
|
||||
passwordLabel: "Password",
|
||||
forgotPassword: "Forgot Password",
|
||||
showPassword: "show password",
|
||||
signIn: "Sign in",
|
||||
signUpText: "Don't have account yet?",
|
||||
signUpLink: "Sign up",
|
||||
toastMessage: "Invalid email or password",
|
||||
};
|
||||
13
cypress-tests/cypress/constants/texts/mongoDb.js
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
export const mongoDbText = {
|
||||
mongoDb: "MongoDB",
|
||||
cypressMongoDb: "cypress-mongodb",
|
||||
errorConnectionRefused: "connect ECONNREFUSED 127.0.0.1:27017",
|
||||
|
||||
optionConnectUsingConnectionString: "Connect using connection string{enter}",
|
||||
labelConnectionString: "Connection string",
|
||||
|
||||
errorInvalisScheme:
|
||||
'Invalid scheme, expected connection string to start with "mongodb://" or "mongodb+srv://"',
|
||||
connectionStringPlaceholder:
|
||||
"mongodb+srv://tooljet:<password>@cluster0.i1vq4.mongodb.net/mydb?retryWrites=true&w=majority",
|
||||
};
|
||||
9
cypress-tests/cypress/constants/texts/mysql.js
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
export const mySqlText = {
|
||||
errorConnectionRefused: "connect ECONNREFUSED",
|
||||
errorUnknownDb: "ER_BAD_DB_ERROR: Unknown database 'test_db1'",
|
||||
errorAccessDeniedAdmin1:
|
||||
"ER_ACCESS_DENIED_ERROR: Access denied for user 'admin1'",
|
||||
errorAccessDeniedAdmin:
|
||||
"ER_ACCESS_DENIED_ERROR: Access denied for user 'admin'",
|
||||
cypressMySql: "cypress-mysql",
|
||||
};
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
export const postgreSqlText = {
|
||||
labelDataSources: "Data sources",
|
||||
labelDataSources: "Datasources",
|
||||
labelAddDataSource: "+ add data source",
|
||||
|
||||
allDataSources: "All Datasources (39)",
|
||||
|
|
|
|||
9
cypress-tests/cypress/constants/texts/redis.js
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
export const redisText = {
|
||||
redis: "Redis",
|
||||
cypressRedis: "cypress-redis",
|
||||
|
||||
errorMaxRetries:
|
||||
'Reached the max retries per request limit (which is 1). Refer to "maxRetriesPerRequest" option for details.',
|
||||
errorPort: "Port should be >= 0 and < 65536. Received 108299.",
|
||||
errorInvalidUserOrPassword: "WRONGPASS invalid username-password pair",
|
||||
};
|
||||
|
|
@ -1,59 +1,82 @@
|
|||
import { loginSelectors } from "Selectors/login";
|
||||
import { commonSelectors } from "Selectors/common";
|
||||
import { loginTexts } from "Texts/login";
|
||||
import { fake } from "Fixtures/fake";
|
||||
import * as login from "Support/utils/login";
|
||||
import { commonText, path } from "Texts/common";
|
||||
|
||||
describe("Login functionality", () => {
|
||||
let user;
|
||||
const invalidEmail = fake.email;
|
||||
const invalidPassword = fake.password;
|
||||
|
||||
before(() => {
|
||||
beforeEach(() => {
|
||||
cy.fixture("credentials/login.json").then((login) => {
|
||||
user = login;
|
||||
});
|
||||
cy.visit("/");
|
||||
});
|
||||
it("Should verify elements on the login page", () => {
|
||||
login.loginPageElements();
|
||||
cy.url().should("include", path.loginPath);
|
||||
cy.get(commonSelectors.pageLogo).should("be.visible");
|
||||
cy.get(commonSelectors.signInHeader).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.signInHeader
|
||||
);
|
||||
cy.get(commonSelectors.workEmailLabel).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.workEmailLabel
|
||||
);
|
||||
cy.get(commonSelectors.passwordLabel).should(($el) => {
|
||||
expect($el.contents().first().text().trim()).to.eq(
|
||||
commonText.passwordLabel
|
||||
);
|
||||
});
|
||||
cy.get(commonSelectors.forgotPasswordLink).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.forgotPasswordLink
|
||||
);
|
||||
cy.get(commonSelectors.loginButton).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.loginButton
|
||||
);
|
||||
|
||||
cy.get(commonSelectors.workEmailInputField).should("be.visible");
|
||||
cy.get(commonSelectors.passwordInputField).should("be.visible");
|
||||
});
|
||||
it("Should not be able to login with invalid credentials", () => {
|
||||
cy.get(loginSelectors.signInButton).click();
|
||||
cy.verifyToastMessage(
|
||||
commonSelectors.toastMessage,
|
||||
loginTexts.toastMessage
|
||||
cy.get(commonSelectors.loginButton).click();
|
||||
cy.get(commonSelectors.emailInputError).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.emailInputError
|
||||
);
|
||||
|
||||
cy.clearAndType(loginSelectors.emailField, invalidEmail);
|
||||
cy.get(loginSelectors.signInButton).click();
|
||||
cy.clearAndType(commonSelectors.workEmailInputField, invalidEmail);
|
||||
cy.get(commonSelectors.loginButton).click();
|
||||
cy.verifyToastMessage(
|
||||
commonSelectors.toastMessage,
|
||||
loginTexts.toastMessage
|
||||
commonText.loginErrorToast
|
||||
);
|
||||
|
||||
cy.get(loginSelectors.emailField).clear();
|
||||
cy.clearAndType(loginSelectors.passwordField, invalidPassword);
|
||||
cy.get(loginSelectors.signInButton).click();
|
||||
cy.verifyToastMessage(
|
||||
commonSelectors.toastMessage,
|
||||
loginTexts.toastMessage
|
||||
cy.get(commonSelectors.workEmailInputField).clear();
|
||||
cy.clearAndType(commonSelectors.passwordInputField, invalidPassword);
|
||||
cy.get(commonSelectors.loginButton).click();
|
||||
cy.get(commonSelectors.emailInputError).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.emailInputError
|
||||
);
|
||||
|
||||
cy.clearAndType(loginSelectors.emailField, user.email);
|
||||
cy.get(loginSelectors.passwordField).clear();
|
||||
cy.get(loginSelectors.signInButton).click();
|
||||
cy.clearAndType(commonSelectors.workEmailInputField, user.email);
|
||||
cy.get(commonSelectors.passwordInputField).clear();
|
||||
cy.get(commonSelectors.loginButton).click();
|
||||
cy.verifyToastMessage(
|
||||
commonSelectors.toastMessage,
|
||||
loginTexts.toastMessage
|
||||
commonText.loginErrorToast
|
||||
);
|
||||
|
||||
cy.get(loginSelectors.emailField).clear();
|
||||
cy.clearAndType(loginSelectors.passwordField, user.password);
|
||||
cy.get(loginSelectors.signInButton).click();
|
||||
cy.verifyToastMessage(
|
||||
commonSelectors.toastMessage,
|
||||
loginTexts.toastMessage
|
||||
cy.get(commonSelectors.workEmailInputField).clear();
|
||||
cy.clearAndType(commonSelectors.passwordInputField, user.password);
|
||||
cy.get(commonSelectors.loginButton).click();
|
||||
cy.get(commonSelectors.emailInputError).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.emailInputError
|
||||
);
|
||||
});
|
||||
it("Should be able to login with valid credentials", () => {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,128 @@
|
|||
import { postgreSqlSelector } from "Selectors/postgreSql";
|
||||
import { postgreSqlText } from "Texts/postgreSql";
|
||||
import { bigqueryText } from "Texts/bigquery";
|
||||
import { firestoreText } from "Texts/firestore";
|
||||
import { commonSelectors } from "Selectors/common";
|
||||
import {
|
||||
fillDataSourceTextField,
|
||||
selectDataSource,
|
||||
} from "Support/utils/postgreSql";
|
||||
|
||||
describe("Data source BigQuery", () => {
|
||||
beforeEach(() => {
|
||||
cy.appUILogin();
|
||||
cy.createApp();
|
||||
});
|
||||
|
||||
it("Should verify elements on BigQuery connection form", () => {
|
||||
cy.get(postgreSqlSelector.leftSidebarDatasourceButton).click();
|
||||
cy.get(postgreSqlSelector.labelDataSources).should(
|
||||
"have.text",
|
||||
postgreSqlText.labelDataSources
|
||||
);
|
||||
|
||||
cy.get(postgreSqlSelector.addDatasourceLink)
|
||||
.should("have.text", postgreSqlText.labelAddDataSource)
|
||||
.click();
|
||||
|
||||
cy.get(postgreSqlSelector.allDatasourceLabelAndCount).should(
|
||||
"have.text",
|
||||
postgreSqlText.allDataSources
|
||||
);
|
||||
cy.get(postgreSqlSelector.databaseLabelAndCount).should(
|
||||
"have.text",
|
||||
postgreSqlText.allDatabase
|
||||
);
|
||||
cy.get(postgreSqlSelector.apiLabelAndCount).should(
|
||||
"have.text",
|
||||
postgreSqlText.allApis
|
||||
);
|
||||
cy.get(postgreSqlSelector.cloudStorageLabelAndCount).should(
|
||||
"have.text",
|
||||
postgreSqlText.allCloudStorage
|
||||
);
|
||||
|
||||
cy.get(postgreSqlSelector.dataSourceSearchInputField).type(
|
||||
bigqueryText.bigQuery
|
||||
);
|
||||
cy.get("[data-cy*='data-source-']")
|
||||
.eq(0)
|
||||
.should("contain", bigqueryText.bigQuery);
|
||||
cy.get('[data-cy="data-source-bigquery"]').click();
|
||||
|
||||
cy.get(postgreSqlSelector.dataSourceNameInputField).should(
|
||||
"have.value",
|
||||
bigqueryText.bigQuery
|
||||
);
|
||||
|
||||
cy.get('[data-cy="label-private-key"]').verifyVisibleElement(
|
||||
"have.text",
|
||||
firestoreText.labelPrivateKey
|
||||
);
|
||||
|
||||
cy.get(postgreSqlSelector.labelIpWhitelist).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.whiteListIpText
|
||||
);
|
||||
cy.get(postgreSqlSelector.buttonCopyIp).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.textCopy
|
||||
);
|
||||
|
||||
cy.get(postgreSqlSelector.linkReadDocumentation).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.readDocumentation
|
||||
);
|
||||
cy.get(postgreSqlSelector.buttonTestConnection)
|
||||
.verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.buttonTextTestConnection
|
||||
)
|
||||
.click();
|
||||
cy.get(postgreSqlSelector.connectionFailedText).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.couldNotConnect
|
||||
);
|
||||
cy.get(postgreSqlSelector.buttonSave).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.buttonTextSave
|
||||
);
|
||||
cy.get(postgreSqlSelector.dangerAlertNotSupportSSL).verifyVisibleElement(
|
||||
"have.text",
|
||||
bigqueryText.errorInvalidEmailId
|
||||
);
|
||||
});
|
||||
|
||||
it("Should verify the functionality of BigQuery connection form.", () => {
|
||||
selectDataSource(bigqueryText.bigQuery);
|
||||
|
||||
cy.clearAndType(
|
||||
'[data-cy="data-source-name-input-filed"]',
|
||||
bigqueryText.cypressBigQuery
|
||||
);
|
||||
|
||||
fillDataSourceTextField(
|
||||
firestoreText.privateKey,
|
||||
bigqueryText.placehlderPrivateKey,
|
||||
JSON.stringify(Cypress.env("bigquery_pvt_key")),
|
||||
"contain",
|
||||
{ parseSpecialCharSequences: false, delay: 0 }
|
||||
);
|
||||
cy.get(postgreSqlSelector.buttonTestConnection).click();
|
||||
cy.get(postgreSqlSelector.textConnectionVerified, {
|
||||
timeout: 10000,
|
||||
}).should("have.text", postgreSqlText.labelConnectionVerified);
|
||||
cy.get(postgreSqlSelector.buttonSave).click();
|
||||
|
||||
cy.verifyToastMessage(
|
||||
commonSelectors.toastMessage,
|
||||
postgreSqlText.toastDSAdded
|
||||
);
|
||||
|
||||
cy.get(postgreSqlSelector.leftSidebarDatasourceButton).click();
|
||||
cy.get(postgreSqlSelector.datasourceLabelOnList)
|
||||
.should("have.text", bigqueryText.cypressBigQuery)
|
||||
.find("button")
|
||||
.should("be.visible");
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,166 @@
|
|||
import { postgreSqlSelector } from "Selectors/postgreSql";
|
||||
import { postgreSqlText } from "Texts/postgreSql";
|
||||
import { dynamoDbText } from "Texts/dynamodb";
|
||||
import { commonSelectors } from "Selectors/common";
|
||||
import {
|
||||
fillDataSourceTextField,
|
||||
selectDataSource,
|
||||
} from "Support/utils/postgreSql";
|
||||
import { verifyCouldnotConnectWithAlert } from "Support/utils/dataSource";
|
||||
|
||||
describe("Data source DynamoDB", () => {
|
||||
beforeEach(() => {
|
||||
cy.appUILogin();
|
||||
cy.createApp();
|
||||
});
|
||||
|
||||
it("Should verify elements on DynamoDB connection form", () => {
|
||||
cy.get(postgreSqlSelector.leftSidebarDatasourceButton).click();
|
||||
cy.get(postgreSqlSelector.labelDataSources).should(
|
||||
"have.text",
|
||||
postgreSqlText.labelDataSources
|
||||
);
|
||||
|
||||
cy.get(postgreSqlSelector.addDatasourceLink)
|
||||
.should("have.text", postgreSqlText.labelAddDataSource)
|
||||
.click();
|
||||
|
||||
cy.get(postgreSqlSelector.allDatasourceLabelAndCount).should(
|
||||
"have.text",
|
||||
postgreSqlText.allDataSources
|
||||
);
|
||||
cy.get(postgreSqlSelector.databaseLabelAndCount).should(
|
||||
"have.text",
|
||||
postgreSqlText.allDatabase
|
||||
);
|
||||
cy.get(postgreSqlSelector.apiLabelAndCount).should(
|
||||
"have.text",
|
||||
postgreSqlText.allApis
|
||||
);
|
||||
cy.get(postgreSqlSelector.cloudStorageLabelAndCount).should(
|
||||
"have.text",
|
||||
postgreSqlText.allCloudStorage
|
||||
);
|
||||
|
||||
cy.get(postgreSqlSelector.dataSourceSearchInputField).type(
|
||||
dynamoDbText.dynamoDb
|
||||
);
|
||||
cy.get("[data-cy*='data-source-']")
|
||||
.eq(0)
|
||||
.should("contain", dynamoDbText.dynamoDb);
|
||||
cy.get('[data-cy="data-source-dynamodb"]').click();
|
||||
|
||||
cy.get(postgreSqlSelector.dataSourceNameInputField).should(
|
||||
"have.value",
|
||||
dynamoDbText.dynamoDb
|
||||
);
|
||||
cy.get('[data-cy="label-region"]').verifyVisibleElement(
|
||||
"have.text",
|
||||
dynamoDbText.region
|
||||
);
|
||||
cy.get('[data-cy="label-access-key"]').verifyVisibleElement(
|
||||
"have.text",
|
||||
dynamoDbText.accessKey
|
||||
);
|
||||
cy.get('[data-cy="label-secret-key"]').verifyVisibleElement(
|
||||
"have.text",
|
||||
dynamoDbText.secretKey
|
||||
);
|
||||
|
||||
cy.get(postgreSqlSelector.labelIpWhitelist).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.whiteListIpText
|
||||
);
|
||||
cy.get(postgreSqlSelector.buttonCopyIp).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.textCopy
|
||||
);
|
||||
|
||||
cy.get(postgreSqlSelector.linkReadDocumentation).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.readDocumentation
|
||||
);
|
||||
cy.get(postgreSqlSelector.buttonTestConnection)
|
||||
.verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.buttonTextTestConnection
|
||||
)
|
||||
.click();
|
||||
cy.get(postgreSqlSelector.connectionFailedText).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.couldNotConnect
|
||||
);
|
||||
cy.get(postgreSqlSelector.buttonSave).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.buttonTextSave
|
||||
);
|
||||
cy.get(postgreSqlSelector.dangerAlertNotSupportSSL).verifyVisibleElement(
|
||||
"have.text",
|
||||
dynamoDbText.errorMissingRegion
|
||||
);
|
||||
});
|
||||
|
||||
it("Should verify the functionality of DynamoDB connection form.", () => {
|
||||
selectDataSource(dynamoDbText.dynamoDb);
|
||||
|
||||
cy.clearAndType(
|
||||
postgreSqlSelector.dataSourceNameInputField,
|
||||
dynamoDbText.cypressDynamoDb
|
||||
);
|
||||
|
||||
cy.get('[data-cy="label-region"]')
|
||||
.parent()
|
||||
.next()
|
||||
.find("input")
|
||||
.type(`N. california{enter}`);
|
||||
fillDataSourceTextField(
|
||||
dynamoDbText.accessKey,
|
||||
dynamoDbText.placeHolderAccessKey,
|
||||
"dynamodb_access_key"
|
||||
);
|
||||
fillDataSourceTextField(
|
||||
dynamoDbText.secretKey,
|
||||
dynamoDbText.placeholderSecretKey,
|
||||
Cypress.env("dynamodb_secret_key")
|
||||
);
|
||||
cy.get(postgreSqlSelector.buttonTestConnection).click();
|
||||
verifyCouldnotConnectWithAlert(dynamoDbText.errorInvalidToken);
|
||||
|
||||
fillDataSourceTextField(
|
||||
dynamoDbText.accessKey,
|
||||
dynamoDbText.placeHolderAccessKey,
|
||||
Cypress.env("dynamodb_access_key")
|
||||
);
|
||||
fillDataSourceTextField(
|
||||
dynamoDbText.secretKey,
|
||||
dynamoDbText.placeholderSecretKey,
|
||||
"dynamodb_secret_key"
|
||||
);
|
||||
cy.get(postgreSqlSelector.buttonTestConnection).click();
|
||||
verifyCouldnotConnectWithAlert(dynamoDbText.errorSignatureMissmatch);
|
||||
|
||||
fillDataSourceTextField(
|
||||
dynamoDbText.secretKey,
|
||||
dynamoDbText.placeholderSecretKey,
|
||||
Cypress.env("dynamodb_secret_key")
|
||||
);
|
||||
|
||||
cy.get(postgreSqlSelector.buttonTestConnection).click();
|
||||
cy.get(postgreSqlSelector.textConnectionVerified, {
|
||||
timeout: 10000,
|
||||
}).should("have.text", postgreSqlText.labelConnectionVerified, {
|
||||
timeout: 10000,
|
||||
});
|
||||
cy.get(postgreSqlSelector.buttonSave).click();
|
||||
|
||||
cy.verifyToastMessage(
|
||||
commonSelectors.toastMessage,
|
||||
postgreSqlText.toastDSAdded
|
||||
);
|
||||
|
||||
cy.get(postgreSqlSelector.leftSidebarDatasourceButton).click();
|
||||
cy.get(postgreSqlSelector.datasourceLabelOnList)
|
||||
.should("contains.text", dynamoDbText.cypressDynamoDb)
|
||||
.should("be.visible");
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,188 @@
|
|||
import { postgreSqlSelector } from "Selectors/postgreSql";
|
||||
import { postgreSqlText } from "Texts/postgreSql";
|
||||
import { elasticsearchText } from "Texts/elasticsearch";
|
||||
import { commonSelectors } from "Selectors/common";
|
||||
import {
|
||||
fillDataSourceTextField,
|
||||
selectDataSource,
|
||||
} from "Support/utils/postgreSql";
|
||||
import { verifyCouldnotConnectWithAlert } from "Support/utils/dataSource";
|
||||
|
||||
describe("Data source Elasticsearch", () => {
|
||||
beforeEach(() => {
|
||||
cy.appUILogin();
|
||||
cy.createApp();
|
||||
});
|
||||
|
||||
it("Should verify elements on Elasticsearch connection form", () => {
|
||||
cy.get(postgreSqlSelector.leftSidebarDatasourceButton).click();
|
||||
cy.get(postgreSqlSelector.labelDataSources).should(
|
||||
"have.text",
|
||||
postgreSqlText.labelDataSources
|
||||
);
|
||||
|
||||
cy.get(postgreSqlSelector.addDatasourceLink)
|
||||
.should("have.text", postgreSqlText.labelAddDataSource)
|
||||
.click();
|
||||
|
||||
cy.get(postgreSqlSelector.allDatasourceLabelAndCount).should(
|
||||
"have.text",
|
||||
postgreSqlText.allDataSources
|
||||
);
|
||||
cy.get(postgreSqlSelector.databaseLabelAndCount).should(
|
||||
"have.text",
|
||||
postgreSqlText.allDatabase
|
||||
);
|
||||
cy.get(postgreSqlSelector.apiLabelAndCount).should(
|
||||
"have.text",
|
||||
postgreSqlText.allApis
|
||||
);
|
||||
cy.get(postgreSqlSelector.cloudStorageLabelAndCount).should(
|
||||
"have.text",
|
||||
postgreSqlText.allCloudStorage
|
||||
);
|
||||
|
||||
cy.get(postgreSqlSelector.dataSourceSearchInputField).type(
|
||||
elasticsearchText.elasticSearch
|
||||
);
|
||||
cy.get("[data-cy*='data-source-']")
|
||||
.eq(0)
|
||||
.should("contain", elasticsearchText.elasticSearch);
|
||||
cy.get('[data-cy="data-source-elasticsearch"]').click();
|
||||
|
||||
cy.get(postgreSqlSelector.dataSourceNameInputField).should(
|
||||
"have.value",
|
||||
elasticsearchText.elasticSearch
|
||||
);
|
||||
cy.get(postgreSqlSelector.labelHost).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.labelHost
|
||||
);
|
||||
cy.get(postgreSqlSelector.labelPort).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.labelPort
|
||||
);
|
||||
cy.get(postgreSqlSelector.labelUserName).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.labelUserName
|
||||
);
|
||||
cy.get(postgreSqlSelector.labelPassword).verifyVisibleElement(
|
||||
"have.text",
|
||||
"Password"
|
||||
);
|
||||
cy.get(postgreSqlSelector.labelSsl).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.labelSSL
|
||||
);
|
||||
cy.get(postgreSqlSelector.labelSSLCertificate).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.sslCertificate
|
||||
);
|
||||
cy.get(postgreSqlSelector.labelIpWhitelist).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.whiteListIpText
|
||||
);
|
||||
cy.get(postgreSqlSelector.buttonCopyIp).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.textCopy
|
||||
);
|
||||
|
||||
cy.get(postgreSqlSelector.linkReadDocumentation).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.readDocumentation
|
||||
);
|
||||
cy.get(postgreSqlSelector.buttonTestConnection)
|
||||
.verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.buttonTextTestConnection
|
||||
)
|
||||
.click();
|
||||
cy.get(postgreSqlSelector.connectionFailedText).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.couldNotConnect
|
||||
);
|
||||
cy.get(postgreSqlSelector.buttonSave).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.buttonTextSave
|
||||
);
|
||||
cy.get(postgreSqlSelector.dangerAlertNotSupportSSL).verifyVisibleElement(
|
||||
"have.text",
|
||||
elasticsearchText.errorConnectionRefused
|
||||
);
|
||||
});
|
||||
|
||||
it("Should verify the functionality of Elasticsearch connection form.", () => {
|
||||
selectDataSource(elasticsearchText.elasticSearch);
|
||||
|
||||
cy.clearAndType(
|
||||
postgreSqlSelector.dataSourceNameInputField,
|
||||
elasticsearchText.cypressElasticsearch
|
||||
);
|
||||
|
||||
fillDataSourceTextField(
|
||||
postgreSqlText.labelHost,
|
||||
postgreSqlText.placeholderEnterHost,
|
||||
"elasticsearch_host"
|
||||
);
|
||||
fillDataSourceTextField(
|
||||
postgreSqlText.labelPort,
|
||||
postgreSqlText.placeholderEnterPort,
|
||||
"443"
|
||||
);
|
||||
|
||||
fillDataSourceTextField(
|
||||
postgreSqlText.labelUserName,
|
||||
postgreSqlText.placeholderEnterUserName,
|
||||
Cypress.env("elasticsearch_user")
|
||||
);
|
||||
|
||||
cy.get(postgreSqlSelector.passwordTextField).type(
|
||||
Cypress.env("elasticsearch_password")
|
||||
);
|
||||
cy.get(postgreSqlSelector.buttonTestConnection).click();
|
||||
verifyCouldnotConnectWithAlert(elasticsearchText.errorGetAddrInfoNotFound);
|
||||
|
||||
fillDataSourceTextField(
|
||||
postgreSqlText.labelHost,
|
||||
postgreSqlText.placeholderEnterHost,
|
||||
Cypress.env("elasticsearch_host")
|
||||
);
|
||||
fillDataSourceTextField(
|
||||
postgreSqlText.labelUserName,
|
||||
postgreSqlText.placeholderEnterUserName,
|
||||
"elasticsearch_user"
|
||||
);
|
||||
cy.get(postgreSqlSelector.buttonTestConnection).click();
|
||||
verifyCouldnotConnectWithAlert("Response Error");
|
||||
|
||||
fillDataSourceTextField(
|
||||
postgreSqlText.labelUserName,
|
||||
postgreSqlText.placeholderEnterUserName,
|
||||
Cypress.env("elasticsearch_user")
|
||||
);
|
||||
cy.get(postgreSqlSelector.passwordTextField)
|
||||
.clear()
|
||||
.type("elasticsearch_password");
|
||||
cy.get(postgreSqlSelector.buttonTestConnection).click();
|
||||
verifyCouldnotConnectWithAlert("Response Error");
|
||||
cy.get(postgreSqlSelector.passwordTextField)
|
||||
.clear()
|
||||
.type(Cypress.env("elasticsearch_password"));
|
||||
|
||||
cy.get(postgreSqlSelector.buttonTestConnection).click();
|
||||
cy.get(postgreSqlSelector.textConnectionVerified, {
|
||||
timeout: 10000,
|
||||
}).should("have.text", postgreSqlText.labelConnectionVerified);
|
||||
cy.get(postgreSqlSelector.buttonSave).click();
|
||||
|
||||
cy.verifyToastMessage(
|
||||
commonSelectors.toastMessage,
|
||||
postgreSqlText.toastDSAdded
|
||||
);
|
||||
|
||||
cy.get(postgreSqlSelector.leftSidebarDatasourceButton).click();
|
||||
cy.get(postgreSqlSelector.datasourceLabelOnList)
|
||||
.should("have.text", elasticsearchText.cypressElasticsearch)
|
||||
.should("be.visible");
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,127 @@
|
|||
import { postgreSqlSelector } from "Selectors/postgreSql";
|
||||
import { postgreSqlText } from "Texts/postgreSql";
|
||||
import { firestoreText } from "Texts/firestore";
|
||||
import { commonSelectors } from "Selectors/common";
|
||||
import {
|
||||
fillDataSourceTextField,
|
||||
selectDataSource,
|
||||
} from "Support/utils/postgreSql";
|
||||
|
||||
describe("Data source Firestore", () => {
|
||||
beforeEach(() => {
|
||||
cy.appUILogin();
|
||||
cy.createApp();
|
||||
});
|
||||
|
||||
it("Should verify elements on Firestore connection form", () => {
|
||||
cy.get(postgreSqlSelector.leftSidebarDatasourceButton).click();
|
||||
cy.get(postgreSqlSelector.labelDataSources).should(
|
||||
"have.text",
|
||||
postgreSqlText.labelDataSources
|
||||
);
|
||||
|
||||
cy.get(postgreSqlSelector.addDatasourceLink)
|
||||
.should("have.text", postgreSqlText.labelAddDataSource)
|
||||
.click();
|
||||
|
||||
cy.get(postgreSqlSelector.allDatasourceLabelAndCount).should(
|
||||
"have.text",
|
||||
postgreSqlText.allDataSources
|
||||
);
|
||||
cy.get(postgreSqlSelector.databaseLabelAndCount).should(
|
||||
"have.text",
|
||||
postgreSqlText.allDatabase
|
||||
);
|
||||
cy.get(postgreSqlSelector.apiLabelAndCount).should(
|
||||
"have.text",
|
||||
postgreSqlText.allApis
|
||||
);
|
||||
cy.get(postgreSqlSelector.cloudStorageLabelAndCount).should(
|
||||
"have.text",
|
||||
postgreSqlText.allCloudStorage
|
||||
);
|
||||
|
||||
cy.get(postgreSqlSelector.dataSourceSearchInputField).type(
|
||||
firestoreText.firestore
|
||||
);
|
||||
cy.get("[data-cy*='data-source-']")
|
||||
.eq(0)
|
||||
.should("contain", firestoreText.firestore);
|
||||
cy.get('[data-cy="data-source-firestore"]').click();
|
||||
|
||||
cy.get(postgreSqlSelector.dataSourceNameInputField).should(
|
||||
"have.value",
|
||||
firestoreText.firestore
|
||||
);
|
||||
|
||||
cy.get('[data-cy="label-private-key"]').verifyVisibleElement(
|
||||
"have.text",
|
||||
firestoreText.labelPrivateKey
|
||||
);
|
||||
|
||||
cy.get(postgreSqlSelector.labelIpWhitelist).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.whiteListIpText
|
||||
);
|
||||
cy.get(postgreSqlSelector.buttonCopyIp).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.textCopy
|
||||
);
|
||||
|
||||
cy.get(postgreSqlSelector.linkReadDocumentation).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.readDocumentation
|
||||
);
|
||||
cy.get(postgreSqlSelector.buttonTestConnection)
|
||||
.verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.buttonTextTestConnection
|
||||
)
|
||||
.click();
|
||||
cy.get(postgreSqlSelector.connectionFailedText).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.couldNotConnect
|
||||
);
|
||||
cy.get(postgreSqlSelector.buttonSave).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.buttonTextSave
|
||||
);
|
||||
cy.get(postgreSqlSelector.dangerAlertNotSupportSSL).verifyVisibleElement(
|
||||
"have.text",
|
||||
firestoreText.errorGcpKeyCouldNotBeParsed
|
||||
);
|
||||
});
|
||||
|
||||
it("Should verify the functionality of Firestore connection form.", () => {
|
||||
selectDataSource(firestoreText.firestore);
|
||||
|
||||
cy.clearAndType(
|
||||
'[data-cy="data-source-name-input-filed"]',
|
||||
firestoreText.cypressFirestore
|
||||
);
|
||||
|
||||
fillDataSourceTextField(
|
||||
firestoreText.privateKey,
|
||||
firestoreText.placeholderPrivateKey,
|
||||
JSON.stringify(Cypress.env("firestore_pvt_key")),
|
||||
"contain",
|
||||
{ parseSpecialCharSequences: false, delay: 0 }
|
||||
);
|
||||
cy.get(postgreSqlSelector.buttonTestConnection).click();
|
||||
cy.get(postgreSqlSelector.textConnectionVerified, {
|
||||
timeout: 10000,
|
||||
}).should("have.text", postgreSqlText.labelConnectionVerified);
|
||||
cy.get(postgreSqlSelector.buttonSave).click();
|
||||
|
||||
cy.verifyToastMessage(
|
||||
commonSelectors.toastMessage,
|
||||
postgreSqlText.toastDSAdded
|
||||
);
|
||||
|
||||
cy.get(postgreSqlSelector.leftSidebarDatasourceButton).click();
|
||||
cy.get(postgreSqlSelector.datasourceLabelOnList)
|
||||
.should("contain.text", firestoreText.cypressFirestore)
|
||||
.find("button")
|
||||
.should("be.visible");
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,183 @@
|
|||
import { postgreSqlSelector } from "Selectors/postgreSql";
|
||||
import { postgreSqlText } from "Texts/postgreSql";
|
||||
import { mongoDbText } from "Texts/mongoDb";
|
||||
import { commonSelectors } from "Selectors/common";
|
||||
import {
|
||||
fillDataSourceTextField,
|
||||
selectDataSource,
|
||||
} from "Support/utils/postgreSql";
|
||||
import { verifyCouldnotConnectWithAlert } from "Support/utils/dataSource";
|
||||
|
||||
describe("Data source MongoDB", () => {
|
||||
beforeEach(() => {
|
||||
cy.appUILogin();
|
||||
cy.createApp();
|
||||
});
|
||||
|
||||
it("Should verify elements on MongoDB connection form", () => {
|
||||
cy.get(postgreSqlSelector.leftSidebarDatasourceButton).click();
|
||||
cy.get(postgreSqlSelector.labelDataSources).should(
|
||||
"have.text",
|
||||
postgreSqlText.labelDataSources
|
||||
);
|
||||
|
||||
cy.get(postgreSqlSelector.addDatasourceLink)
|
||||
.should("have.text", postgreSqlText.labelAddDataSource)
|
||||
.click();
|
||||
|
||||
cy.get(postgreSqlSelector.allDatasourceLabelAndCount).should(
|
||||
"have.text",
|
||||
postgreSqlText.allDataSources
|
||||
);
|
||||
cy.get(postgreSqlSelector.databaseLabelAndCount).should(
|
||||
"have.text",
|
||||
postgreSqlText.allDatabase
|
||||
);
|
||||
cy.get(postgreSqlSelector.apiLabelAndCount).should(
|
||||
"have.text",
|
||||
postgreSqlText.allApis
|
||||
);
|
||||
cy.get(postgreSqlSelector.cloudStorageLabelAndCount).should(
|
||||
"have.text",
|
||||
postgreSqlText.allCloudStorage
|
||||
);
|
||||
|
||||
cy.get(postgreSqlSelector.dataSourceSearchInputField).type(
|
||||
mongoDbText.mongoDb
|
||||
);
|
||||
cy.get("[data-cy*='data-source-']")
|
||||
.eq(0)
|
||||
.should("contain", mongoDbText.mongoDb);
|
||||
cy.get('[data-cy="data-source-mongodb"]').click();
|
||||
|
||||
cy.get(postgreSqlSelector.dataSourceNameInputField).should(
|
||||
"have.value",
|
||||
mongoDbText.mongoDb
|
||||
);
|
||||
cy.get(postgreSqlSelector.labelHost).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.labelHost
|
||||
);
|
||||
cy.get(postgreSqlSelector.labelPort).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.labelPort
|
||||
);
|
||||
cy.get(postgreSqlSelector.labelDbName).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.labelDbName
|
||||
);
|
||||
cy.get(postgreSqlSelector.labelUserName).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.labelUserName
|
||||
);
|
||||
cy.get(postgreSqlSelector.labelPassword).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.labelPassword
|
||||
);
|
||||
cy.get(postgreSqlSelector.labelIpWhitelist).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.whiteListIpText
|
||||
);
|
||||
cy.get(postgreSqlSelector.buttonCopyIp).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.textCopy
|
||||
);
|
||||
|
||||
cy.get(postgreSqlSelector.linkReadDocumentation).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.readDocumentation
|
||||
);
|
||||
cy.get(postgreSqlSelector.buttonTestConnection)
|
||||
.verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.buttonTextTestConnection
|
||||
)
|
||||
.click();
|
||||
cy.get(postgreSqlSelector.connectionFailedText).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.couldNotConnect,
|
||||
{ timeout: 65000 }
|
||||
);
|
||||
cy.get(postgreSqlSelector.buttonSave).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.buttonTextSave
|
||||
);
|
||||
cy.get(postgreSqlSelector.dangerAlertNotSupportSSL).verifyVisibleElement(
|
||||
"have.text",
|
||||
mongoDbText.errorConnectionRefused
|
||||
);
|
||||
cy.get('[data-cy="query-select-dropdown"]').type(
|
||||
mongoDbText.optionConnectUsingConnectionString
|
||||
);
|
||||
cy.get('[data-cy="label-connection-string"]').verifyVisibleElement(
|
||||
"have.text",
|
||||
mongoDbText.labelConnectionString
|
||||
);
|
||||
cy.get(postgreSqlSelector.labelIpWhitelist).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.whiteListIpText
|
||||
);
|
||||
cy.get(postgreSqlSelector.buttonCopyIp).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.textCopy
|
||||
);
|
||||
|
||||
cy.get(postgreSqlSelector.linkReadDocumentation).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.readDocumentation
|
||||
);
|
||||
cy.get(postgreSqlSelector.buttonTestConnection)
|
||||
.verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.buttonTextTestConnection
|
||||
)
|
||||
.click();
|
||||
cy.get(postgreSqlSelector.connectionFailedText).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.couldNotConnect,
|
||||
{ timeout: 60000 }
|
||||
);
|
||||
verifyCouldnotConnectWithAlert(mongoDbText.errorInvalisScheme);
|
||||
cy.get(postgreSqlSelector.buttonSave).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.buttonTextSave
|
||||
);
|
||||
});
|
||||
|
||||
it("Should verify the functionality of MongoDB connection form.", () => {
|
||||
selectDataSource(mongoDbText.mongoDb);
|
||||
|
||||
cy.clearAndType(
|
||||
'[data-cy="data-source-name-input-filed"]',
|
||||
mongoDbText.cypressMongoDb
|
||||
);
|
||||
|
||||
cy.get('[data-cy="query-select-dropdown"]').type(
|
||||
mongoDbText.optionConnectUsingConnectionString
|
||||
);
|
||||
|
||||
fillDataSourceTextField(
|
||||
mongoDbText.labelConnectionString,
|
||||
mongoDbText.connectionStringPlaceholder,
|
||||
Cypress.env("mongodb_connString"),
|
||||
"contain",
|
||||
{ parseSpecialCharSequences: false, delay: 0 }
|
||||
);
|
||||
cy.get(postgreSqlSelector.buttonTestConnection).click();
|
||||
cy.get(postgreSqlSelector.textConnectionVerified, {
|
||||
timeout: 10000,
|
||||
}).should("have.text", postgreSqlText.labelConnectionVerified);
|
||||
cy.get(postgreSqlSelector.buttonSave).click();
|
||||
|
||||
cy.verifyToastMessage(
|
||||
commonSelectors.toastMessage,
|
||||
postgreSqlText.toastDSAdded
|
||||
);
|
||||
|
||||
cy.get(postgreSqlSelector.leftSidebarDatasourceButton).click();
|
||||
cy.get(postgreSqlSelector.datasourceLabelOnList)
|
||||
.should("have.text", mongoDbText.cypressMongoDb)
|
||||
.find("button")
|
||||
.should("be.visible");
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,181 @@
|
|||
import { postgreSqlSelector } from "Selectors/postgreSql";
|
||||
import { postgreSqlText } from "Texts/postgreSql";
|
||||
import { mySqlText } from "Texts/mysql";
|
||||
import { commonSelectors } from "Selectors/common";
|
||||
import {
|
||||
fillDataSourceTextField,
|
||||
selectDataSource,
|
||||
} from "Support/utils/postgreSql";
|
||||
import { verifyCouldnotConnectWithAlert } from "Support/utils/dataSource";
|
||||
describe("Data sources MySql", () => {
|
||||
beforeEach(() => {
|
||||
cy.appUILogin();
|
||||
cy.createApp();
|
||||
});
|
||||
|
||||
it("Should verify elements on MySQL connection form", () => {
|
||||
cy.get(postgreSqlSelector.leftSidebarDatasourceButton).click();
|
||||
cy.get(postgreSqlSelector.labelDataSources).should(
|
||||
"have.text",
|
||||
postgreSqlText.labelDataSources
|
||||
);
|
||||
|
||||
cy.get(postgreSqlSelector.addDatasourceLink)
|
||||
.should("have.text", postgreSqlText.labelAddDataSource)
|
||||
.click();
|
||||
|
||||
cy.get(postgreSqlSelector.allDatasourceLabelAndCount).should(
|
||||
"have.text",
|
||||
postgreSqlText.allDataSources
|
||||
);
|
||||
cy.get(postgreSqlSelector.databaseLabelAndCount).should(
|
||||
"have.text",
|
||||
postgreSqlText.allDatabase
|
||||
);
|
||||
cy.get(postgreSqlSelector.apiLabelAndCount).should(
|
||||
"have.text",
|
||||
postgreSqlText.allApis
|
||||
);
|
||||
cy.get(postgreSqlSelector.cloudStorageLabelAndCount).should(
|
||||
"have.text",
|
||||
postgreSqlText.allCloudStorage
|
||||
);
|
||||
|
||||
cy.get(postgreSqlSelector.dataSourceSearchInputField).type("MySQL");
|
||||
cy.get("[data-cy*='data-source-']").eq(0).should("contain", "MySQL");
|
||||
cy.get('[data-cy="data-source-mysql"]').click();
|
||||
|
||||
cy.get(postgreSqlSelector.dataSourceNameInputField).should(
|
||||
"have.value",
|
||||
"MySQL"
|
||||
);
|
||||
cy.get(postgreSqlSelector.labelHost).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.labelHost
|
||||
);
|
||||
cy.get(postgreSqlSelector.labelPort).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.labelPort
|
||||
);
|
||||
cy.get(postgreSqlSelector.labelSsl).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.labelSSL
|
||||
);
|
||||
cy.get(postgreSqlSelector.labelDbName).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.labelDbName
|
||||
);
|
||||
cy.get(postgreSqlSelector.labelUserName).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.labelUserName
|
||||
);
|
||||
cy.get(postgreSqlSelector.labelPassword).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.labelPassword
|
||||
);
|
||||
|
||||
cy.get(postgreSqlSelector.labelIpWhitelist).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.whiteListIpText
|
||||
);
|
||||
cy.get(postgreSqlSelector.buttonCopyIp).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.textCopy
|
||||
);
|
||||
|
||||
cy.get(postgreSqlSelector.linkReadDocumentation).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.readDocumentation
|
||||
);
|
||||
cy.get(postgreSqlSelector.buttonTestConnection)
|
||||
.verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.buttonTextTestConnection
|
||||
)
|
||||
.click();
|
||||
cy.get(postgreSqlSelector.buttonSave).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.buttonTextSave
|
||||
);
|
||||
verifyCouldnotConnectWithAlert(mySqlText.errorConnectionRefused);
|
||||
});
|
||||
|
||||
it("Should verify the functionality of MySQL connection form.", () => {
|
||||
selectDataSource("MySQL");
|
||||
|
||||
cy.clearAndType(
|
||||
'[data-cy="data-source-name-input-filed"]',
|
||||
mySqlText.cypressMySql
|
||||
);
|
||||
|
||||
fillDataSourceTextField(
|
||||
postgreSqlText.labelHost,
|
||||
postgreSqlText.placeholderEnterHost,
|
||||
Cypress.env("mysql_host")
|
||||
);
|
||||
fillDataSourceTextField(
|
||||
postgreSqlText.labelPort,
|
||||
postgreSqlText.placeholderEnterPort,
|
||||
"3306"
|
||||
);
|
||||
fillDataSourceTextField(
|
||||
postgreSqlText.labelDbName,
|
||||
postgreSqlText.placeholderNameOfDB,
|
||||
"test_db1"
|
||||
);
|
||||
fillDataSourceTextField(
|
||||
postgreSqlText.labelUserName,
|
||||
postgreSqlText.placeholderEnterUserName,
|
||||
"admin"
|
||||
);
|
||||
|
||||
cy.get(postgreSqlSelector.passwordTextField).type(
|
||||
Cypress.env("mysql_password")
|
||||
);
|
||||
|
||||
cy.get(postgreSqlSelector.buttonTestConnection).click();
|
||||
verifyCouldnotConnectWithAlert(mySqlText.errorUnknownDb);
|
||||
fillDataSourceTextField(
|
||||
postgreSqlText.labelDbName,
|
||||
postgreSqlText.placeholderNameOfDB,
|
||||
"test_db"
|
||||
);
|
||||
fillDataSourceTextField(
|
||||
postgreSqlText.labelUserName,
|
||||
postgreSqlText.placeholderEnterUserName,
|
||||
"admin1"
|
||||
);
|
||||
cy.get(postgreSqlSelector.buttonTestConnection).click();
|
||||
verifyCouldnotConnectWithAlert(mySqlText.errorAccessDeniedAdmin1);
|
||||
|
||||
fillDataSourceTextField(
|
||||
postgreSqlText.labelUserName,
|
||||
postgreSqlText.placeholderEnterUserName,
|
||||
"admin"
|
||||
);
|
||||
cy.get(postgreSqlSelector.passwordTextField).type("testpassword");
|
||||
|
||||
cy.get(postgreSqlSelector.buttonTestConnection).click();
|
||||
verifyCouldnotConnectWithAlert(mySqlText.errorAccessDeniedAdmin);
|
||||
cy.get(postgreSqlSelector.passwordTextField).type(
|
||||
`{selectAll}{backspace}${Cypress.env("mysql_password")}`
|
||||
);
|
||||
cy.get(postgreSqlSelector.buttonTestConnection).click();
|
||||
|
||||
cy.get(postgreSqlSelector.textConnectionVerified, {
|
||||
timeout: 10000,
|
||||
}).should("have.text", postgreSqlText.labelConnectionVerified);
|
||||
cy.get(postgreSqlSelector.buttonSave).click();
|
||||
|
||||
cy.verifyToastMessage(
|
||||
commonSelectors.toastMessage,
|
||||
postgreSqlText.toastDSAdded
|
||||
);
|
||||
|
||||
cy.get(postgreSqlSelector.leftSidebarDatasourceButton).click();
|
||||
cy.get(postgreSqlSelector.datasourceLabelOnList)
|
||||
.should("have.text", mySqlText.cypressMySql)
|
||||
.find("button")
|
||||
.should("be.visible");
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,188 @@
|
|||
import { postgreSqlSelector } from "Selectors/postgreSql";
|
||||
import { postgreSqlText } from "Texts/postgreSql";
|
||||
import { redisText } from "Texts/redis";
|
||||
import { commonSelectors } from "Selectors/common";
|
||||
import {
|
||||
fillDataSourceTextField,
|
||||
selectDataSource,
|
||||
} from "Support/utils/postgreSql";
|
||||
import { verifyCouldnotConnectWithAlert } from "Support/utils/dataSource";
|
||||
|
||||
describe("Data source Redis", () => {
|
||||
beforeEach(() => {
|
||||
cy.appUILogin();
|
||||
cy.createApp();
|
||||
});
|
||||
|
||||
it("Should verify elements on connecti Redison form", () => {
|
||||
cy.get(postgreSqlSelector.leftSidebarDatasourceButton).click();
|
||||
cy.get(postgreSqlSelector.labelDataSources).should(
|
||||
"have.text",
|
||||
postgreSqlText.labelDataSources
|
||||
);
|
||||
|
||||
cy.get(postgreSqlSelector.addDatasourceLink)
|
||||
.should("have.text", postgreSqlText.labelAddDataSource)
|
||||
.click();
|
||||
|
||||
cy.get(postgreSqlSelector.allDatasourceLabelAndCount).should(
|
||||
"have.text",
|
||||
postgreSqlText.allDataSources
|
||||
);
|
||||
cy.get(postgreSqlSelector.databaseLabelAndCount).should(
|
||||
"have.text",
|
||||
postgreSqlText.allDatabase
|
||||
);
|
||||
cy.get(postgreSqlSelector.apiLabelAndCount).should(
|
||||
"have.text",
|
||||
postgreSqlText.allApis
|
||||
);
|
||||
cy.get(postgreSqlSelector.cloudStorageLabelAndCount).should(
|
||||
"have.text",
|
||||
postgreSqlText.allCloudStorage
|
||||
);
|
||||
|
||||
cy.get(postgreSqlSelector.dataSourceSearchInputField).type(redisText.redis);
|
||||
cy.get("[data-cy*='data-source-']")
|
||||
.eq(0)
|
||||
.should("contain", redisText.redis);
|
||||
cy.get('[data-cy="data-source-redis"]').click();
|
||||
|
||||
cy.get(postgreSqlSelector.dataSourceNameInputField).should(
|
||||
"have.value",
|
||||
redisText.redis
|
||||
);
|
||||
cy.get(postgreSqlSelector.labelHost).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.labelHost
|
||||
);
|
||||
fillDataSourceTextField(
|
||||
postgreSqlText.labelHost,
|
||||
postgreSqlText.placeholderEnterHost,
|
||||
"redis_host"
|
||||
);
|
||||
cy.get(postgreSqlSelector.labelPort).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.labelPort
|
||||
);
|
||||
cy.get(postgreSqlSelector.labelUserName).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.labelUserName
|
||||
);
|
||||
cy.get(postgreSqlSelector.labelPassword).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.labelPassword
|
||||
);
|
||||
cy.get(postgreSqlSelector.labelIpWhitelist).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.whiteListIpText
|
||||
);
|
||||
cy.get(postgreSqlSelector.buttonCopyIp).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.textCopy
|
||||
);
|
||||
|
||||
cy.get(postgreSqlSelector.linkReadDocumentation).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.readDocumentation
|
||||
);
|
||||
cy.get(postgreSqlSelector.buttonTestConnection)
|
||||
.verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.buttonTextTestConnection
|
||||
)
|
||||
.click();
|
||||
cy.get(postgreSqlSelector.buttonSave).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.buttonTextSave
|
||||
);
|
||||
verifyCouldnotConnectWithAlert(redisText.errorMaxRetries);
|
||||
});
|
||||
it("Should verify the functionality of Redis connection form.", () => {
|
||||
selectDataSource(redisText.redis);
|
||||
|
||||
cy.clearAndType(
|
||||
'[data-cy="data-source-name-input-filed"]',
|
||||
redisText.cypressRedis
|
||||
);
|
||||
|
||||
fillDataSourceTextField(
|
||||
postgreSqlText.labelHost,
|
||||
postgreSqlText.placeholderEnterHost,
|
||||
"redis_host"
|
||||
);
|
||||
fillDataSourceTextField(
|
||||
postgreSqlText.labelPort,
|
||||
postgreSqlText.placeholderEnterPort,
|
||||
Cypress.env("redis_port")
|
||||
);
|
||||
fillDataSourceTextField(
|
||||
postgreSqlText.labelUserName,
|
||||
postgreSqlText.placeholderEnterUserName,
|
||||
"dev@tooljet.io"
|
||||
);
|
||||
cy.get(postgreSqlSelector.passwordTextField).type(
|
||||
Cypress.env("redis_password")
|
||||
);
|
||||
|
||||
cy.get(postgreSqlSelector.buttonTestConnection).click();
|
||||
verifyCouldnotConnectWithAlert(redisText.errorMaxRetries);
|
||||
|
||||
fillDataSourceTextField(
|
||||
postgreSqlText.labelHost,
|
||||
postgreSqlText.placeholderEnterHost,
|
||||
Cypress.env("redis_host")
|
||||
);
|
||||
fillDataSourceTextField(
|
||||
postgreSqlText.labelPort,
|
||||
postgreSqlText.placeholderEnterPort,
|
||||
"108299"
|
||||
);
|
||||
cy.get(postgreSqlSelector.buttonTestConnection).click();
|
||||
verifyCouldnotConnectWithAlert(redisText.errorPort);
|
||||
|
||||
fillDataSourceTextField(
|
||||
postgreSqlText.labelPort,
|
||||
postgreSqlText.placeholderEnterPort,
|
||||
Cypress.env("redis_port")
|
||||
);
|
||||
cy.get(postgreSqlSelector.passwordTextField).type(
|
||||
`{selectAll}{backspace}"redis_password"`
|
||||
);
|
||||
cy.get(postgreSqlSelector.buttonTestConnection).click();
|
||||
verifyCouldnotConnectWithAlert(redisText.errorInvalidUserOrPassword);
|
||||
|
||||
cy.get(postgreSqlSelector.passwordTextField).type(
|
||||
`{selectAll}{backspace}${Cypress.env("redis_password")}`
|
||||
);
|
||||
fillDataSourceTextField(
|
||||
postgreSqlText.labelUserName,
|
||||
postgreSqlText.placeholderEnterUserName,
|
||||
"dev@tooljet.com"
|
||||
);
|
||||
cy.get(postgreSqlSelector.buttonTestConnection).click();
|
||||
verifyCouldnotConnectWithAlert(redisText.errorInvalidUserOrPassword);
|
||||
|
||||
fillDataSourceTextField(
|
||||
postgreSqlText.labelUserName,
|
||||
postgreSqlText.placeholderEnterUserName,
|
||||
"dev@tooljet.io"
|
||||
);
|
||||
cy.get(postgreSqlSelector.buttonTestConnection).click();
|
||||
cy.get(postgreSqlSelector.textConnectionVerified, {
|
||||
timeout: 10000,
|
||||
}).should("have.text", postgreSqlText.labelConnectionVerified);
|
||||
cy.get(postgreSqlSelector.buttonSave).click();
|
||||
|
||||
cy.verifyToastMessage(
|
||||
commonSelectors.toastMessage,
|
||||
postgreSqlText.toastDSAdded
|
||||
);
|
||||
|
||||
cy.get(postgreSqlSelector.leftSidebarDatasourceButton).click();
|
||||
cy.get(postgreSqlSelector.datasourceLabelOnList)
|
||||
.should("have.text", redisText.cypressRedis)
|
||||
.find("button")
|
||||
.should("be.visible");
|
||||
});
|
||||
});
|
||||
176
cypress-tests/cypress/e2e/editor/data-source/s3HappyPath.cy.js
Normal file
|
|
@ -0,0 +1,176 @@
|
|||
import { postgreSqlSelector } from "Selectors/postgreSql";
|
||||
import { s3Selector } from "Selectors/awss3";
|
||||
import { postgreSqlText } from "Texts/postgreSql";
|
||||
import { s3Text } from "Texts/awss3";
|
||||
import { commonSelectors } from "Selectors/common";
|
||||
import {
|
||||
fillDataSourceTextField,
|
||||
selectDataSource,
|
||||
} from "Support/utils/postgreSql";
|
||||
import { verifyCouldnotConnectWithAlert } from "Support/utils/dataSource";
|
||||
describe("Data sources AWS S3", () => {
|
||||
beforeEach(() => {
|
||||
cy.appUILogin();
|
||||
cy.createApp();
|
||||
});
|
||||
|
||||
it("Should verify elements on AWS S3 connection form", () => {
|
||||
cy.get(postgreSqlSelector.leftSidebarDatasourceButton).click();
|
||||
cy.get(postgreSqlSelector.labelDataSources).should(
|
||||
"have.text",
|
||||
postgreSqlText.labelDataSources
|
||||
);
|
||||
|
||||
cy.get(postgreSqlSelector.addDatasourceLink)
|
||||
.should("have.text", postgreSqlText.labelAddDataSource)
|
||||
.click();
|
||||
|
||||
cy.get(postgreSqlSelector.allDatasourceLabelAndCount).should(
|
||||
"have.text",
|
||||
postgreSqlText.allDataSources
|
||||
);
|
||||
cy.get(postgreSqlSelector.databaseLabelAndCount).should(
|
||||
"have.text",
|
||||
postgreSqlText.allDatabase
|
||||
);
|
||||
cy.get(postgreSqlSelector.apiLabelAndCount).should(
|
||||
"have.text",
|
||||
postgreSqlText.allApis
|
||||
);
|
||||
cy.get(postgreSqlSelector.cloudStorageLabelAndCount).should(
|
||||
"have.text",
|
||||
postgreSqlText.allCloudStorage
|
||||
);
|
||||
|
||||
cy.get(postgreSqlSelector.dataSourceSearchInputField).type(s3Text.awsS3);
|
||||
cy.get("[data-cy*='data-source-']").eq(0).should("contain", s3Text.awsS3);
|
||||
cy.get(s3Selector.awsDatasource).click();
|
||||
|
||||
cy.get(postgreSqlSelector.dataSourceNameInputField).should(
|
||||
"have.value",
|
||||
s3Text.awsS3
|
||||
);
|
||||
cy.get(s3Selector.accessKeyLabel).verifyVisibleElement(
|
||||
"have.text",
|
||||
s3Text.accessKey
|
||||
);
|
||||
cy.get(s3Selector.secretKeyLabel).verifyVisibleElement(
|
||||
"have.text",
|
||||
s3Text.secretKey
|
||||
);
|
||||
cy.get(s3Selector.regionLabel).verifyVisibleElement(
|
||||
"have.text",
|
||||
s3Text.labelRegion
|
||||
);
|
||||
cy.get(s3Selector.customEndpointLabel)
|
||||
.verifyVisibleElement("have.text", s3Text.customEndpoint)
|
||||
.next()
|
||||
.find("input")
|
||||
.click();
|
||||
|
||||
cy.get(s3Selector.customEndpointInput).should("be.visible");
|
||||
|
||||
cy.get(postgreSqlSelector.labelIpWhitelist).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.whiteListIpText
|
||||
);
|
||||
cy.get(postgreSqlSelector.buttonCopyIp).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.textCopy
|
||||
);
|
||||
|
||||
cy.get(postgreSqlSelector.linkReadDocumentation).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.readDocumentation
|
||||
);
|
||||
cy.get(postgreSqlSelector.buttonTestConnection)
|
||||
.verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.buttonTextTestConnection
|
||||
)
|
||||
.click();
|
||||
cy.get(postgreSqlSelector.buttonSave).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.buttonTextSave
|
||||
);
|
||||
verifyCouldnotConnectWithAlert(s3Text.alertRegionIsMissing);
|
||||
});
|
||||
|
||||
it("Should verify the functionality of AWS S3 connection form.", () => {
|
||||
selectDataSource(s3Text.awsS3);
|
||||
|
||||
cy.clearAndType(s3Selector.dataSourceNameInput, s3Text.cypressAwsS3);
|
||||
|
||||
fillDataSourceTextField(
|
||||
s3Text.accessKey,
|
||||
s3Text.placeholderEnterAccessKey,
|
||||
Cypress.env("aws_access")
|
||||
);
|
||||
|
||||
cy.get(postgreSqlSelector.buttonTestConnection).click();
|
||||
verifyCouldnotConnectWithAlert(s3Text.alertRegionIsMissing);
|
||||
|
||||
fillDataSourceTextField(
|
||||
"Secret key",
|
||||
s3Text.placeholderEnterSecretKey,
|
||||
Cypress.env("aws_secret"),
|
||||
"contain"
|
||||
);
|
||||
|
||||
cy.get(s3Selector.regionLabel)
|
||||
.next()
|
||||
.find("input")
|
||||
.type(`${s3Text.region}{enter}`);
|
||||
|
||||
cy.get(s3Selector.customEndpointLabel)
|
||||
.verifyVisibleElement("have.text", s3Text.customEndpoint)
|
||||
.next()
|
||||
.find("input")
|
||||
.click();
|
||||
|
||||
cy.get(postgreSqlSelector.buttonTestConnection).click();
|
||||
verifyCouldnotConnectWithAlert(s3Text.alertInvalidUrl);
|
||||
cy.get(s3Selector.customEndpointLabel)
|
||||
.verifyVisibleElement("have.text", s3Text.customEndpoint)
|
||||
.next()
|
||||
.find("input")
|
||||
.click();
|
||||
|
||||
fillDataSourceTextField(
|
||||
s3Text.accessKey,
|
||||
s3Text.placeholderEnterAccessKey,
|
||||
"aws_access"
|
||||
);
|
||||
|
||||
cy.get(postgreSqlSelector.buttonTestConnection).click();
|
||||
verifyCouldnotConnectWithAlert(s3Text.accessKeyError);
|
||||
|
||||
fillDataSourceTextField(
|
||||
s3Text.accessKey,
|
||||
s3Text.placeholderEnterAccessKey,
|
||||
Cypress.env("aws_access")
|
||||
);
|
||||
fillDataSourceTextField(
|
||||
"Secret key",
|
||||
s3Text.placeholderEnterSecretKey,
|
||||
"aws_secret",
|
||||
"contain"
|
||||
);
|
||||
|
||||
cy.get(postgreSqlSelector.buttonTestConnection).click();
|
||||
|
||||
verifyCouldnotConnectWithAlert(s3Text.sinatureError);
|
||||
cy.get(postgreSqlSelector.buttonSave).click();
|
||||
|
||||
cy.verifyToastMessage(
|
||||
commonSelectors.toastMessage,
|
||||
postgreSqlText.toastDSAdded
|
||||
);
|
||||
|
||||
cy.get(postgreSqlSelector.leftSidebarDatasourceButton).click();
|
||||
cy.get(postgreSqlSelector.datasourceLabelOnList)
|
||||
.should("have.text", s3Text.cypressAwsS3)
|
||||
.find("button")
|
||||
.should("be.visible");
|
||||
});
|
||||
});
|
||||
145
cypress-tests/cypress/e2e/editor/data-source/smtpHappyPath.cy.js
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
import { postgreSqlSelector } from "Selectors/postgreSql";
|
||||
import { postgreSqlText } from "Texts/postgreSql";
|
||||
import { commonSelectors } from "Selectors/common";
|
||||
import {
|
||||
fillDataSourceTextField,
|
||||
selectDataSource,
|
||||
} from "Support/utils/postgreSql";
|
||||
|
||||
describe("Data source SMTP", () => {
|
||||
beforeEach(() => {
|
||||
cy.appUILogin();
|
||||
cy.createApp();
|
||||
});
|
||||
|
||||
it("Should verify elements on SMTP connection form", () => {
|
||||
cy.get(postgreSqlSelector.leftSidebarDatasourceButton).click();
|
||||
cy.get(postgreSqlSelector.labelDataSources).should(
|
||||
"have.text",
|
||||
postgreSqlText.labelDataSources
|
||||
);
|
||||
|
||||
cy.get(postgreSqlSelector.addDatasourceLink)
|
||||
.should("have.text", postgreSqlText.labelAddDataSource)
|
||||
.click();
|
||||
|
||||
cy.get(postgreSqlSelector.allDatasourceLabelAndCount).should(
|
||||
"have.text",
|
||||
postgreSqlText.allDataSources
|
||||
);
|
||||
cy.get(postgreSqlSelector.databaseLabelAndCount).should(
|
||||
"have.text",
|
||||
postgreSqlText.allDatabase
|
||||
);
|
||||
cy.get(postgreSqlSelector.apiLabelAndCount).should(
|
||||
"have.text",
|
||||
postgreSqlText.allApis
|
||||
);
|
||||
cy.get(postgreSqlSelector.cloudStorageLabelAndCount).should(
|
||||
"have.text",
|
||||
postgreSqlText.allCloudStorage
|
||||
);
|
||||
|
||||
cy.get(postgreSqlSelector.dataSourceSearchInputField).type("SMTP");
|
||||
cy.get("[data-cy*='data-source-']").eq(0).should("contain", "SMTP");
|
||||
cy.get('[data-cy="data-source-smtp"]').click();
|
||||
|
||||
cy.get(postgreSqlSelector.dataSourceNameInputField).should(
|
||||
"have.value",
|
||||
"SMTP"
|
||||
);
|
||||
cy.get(postgreSqlSelector.labelHost).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.labelHost
|
||||
);
|
||||
cy.get(postgreSqlSelector.labelPort).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.labelPort
|
||||
);
|
||||
cy.get('[data-cy="label-user"]').verifyVisibleElement("have.text", "User");
|
||||
cy.get(postgreSqlSelector.labelPassword).verifyVisibleElement(
|
||||
"have.text",
|
||||
"Password"
|
||||
);
|
||||
|
||||
cy.get(postgreSqlSelector.labelIpWhitelist).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.whiteListIpText
|
||||
);
|
||||
cy.get(postgreSqlSelector.buttonCopyIp).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.textCopy
|
||||
);
|
||||
|
||||
cy.get(postgreSqlSelector.linkReadDocumentation).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.readDocumentation
|
||||
);
|
||||
cy.get(postgreSqlSelector.buttonTestConnection)
|
||||
.verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.buttonTextTestConnection
|
||||
)
|
||||
.click();
|
||||
cy.get(postgreSqlSelector.connectionFailedText).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.couldNotConnect
|
||||
);
|
||||
cy.get(postgreSqlSelector.buttonSave).verifyVisibleElement(
|
||||
"have.text",
|
||||
postgreSqlText.buttonTextSave
|
||||
);
|
||||
cy.get(postgreSqlSelector.dangerAlertNotSupportSSL).verifyVisibleElement(
|
||||
"have.text",
|
||||
"Invalid credentials"
|
||||
);
|
||||
});
|
||||
|
||||
it("Should verify the functionality of SMTP connection form.", () => {
|
||||
selectDataSource("SMTP");
|
||||
|
||||
cy.clearAndType(
|
||||
postgreSqlSelector.dataSourceNameInputField,
|
||||
"cypress-smtp"
|
||||
);
|
||||
|
||||
fillDataSourceTextField(
|
||||
postgreSqlText.labelHost,
|
||||
postgreSqlText.placeholderEnterHost,
|
||||
Cypress.env("smtp_host")
|
||||
);
|
||||
fillDataSourceTextField(
|
||||
postgreSqlText.labelPort,
|
||||
"Recommended port 465 (Secured)",
|
||||
Cypress.env("smtp_port")
|
||||
);
|
||||
|
||||
fillDataSourceTextField(
|
||||
"User",
|
||||
postgreSqlText.placeholderEnterUserName,
|
||||
Cypress.env("smtp_user")
|
||||
);
|
||||
|
||||
cy.get(postgreSqlSelector.passwordTextField).type(
|
||||
Cypress.env("smtp_password")
|
||||
);
|
||||
|
||||
cy.get(postgreSqlSelector.buttonTestConnection).click();
|
||||
cy.get(postgreSqlSelector.textConnectionVerified, {
|
||||
timeout: 20000,
|
||||
}).should("have.text", postgreSqlText.labelConnectionVerified, {
|
||||
timeout: 10000,
|
||||
});
|
||||
cy.get(postgreSqlSelector.buttonSave).click();
|
||||
|
||||
cy.verifyToastMessage(
|
||||
commonSelectors.toastMessage,
|
||||
postgreSqlText.toastDSAdded
|
||||
);
|
||||
|
||||
cy.get(postgreSqlSelector.leftSidebarDatasourceButton).click();
|
||||
cy.get(postgreSqlSelector.datasourceLabelOnList)
|
||||
.should("have.text", "cypress-smtp")
|
||||
.should("be.visible");
|
||||
});
|
||||
});
|
||||
|
|
@ -3,9 +3,7 @@ import { buttonText } from "Texts/button";
|
|||
import { fake } from "Fixtures/fake";
|
||||
import { commonWidgetText } from "Texts/common";
|
||||
|
||||
import {
|
||||
verifyControlComponentAction,
|
||||
} from "Support/utils/button";
|
||||
import { verifyControlComponentAction } from "Support/utils/button";
|
||||
|
||||
import {
|
||||
openAccordion,
|
||||
|
|
@ -25,12 +23,10 @@ import {
|
|||
verifyTooltip,
|
||||
editAndVerifyWidgetName,
|
||||
verifyPropertiesGeneralAccordion,
|
||||
verifyStylesGeneralAccordion
|
||||
|
||||
verifyStylesGeneralAccordion,
|
||||
} from "Support/utils/commonWidget";
|
||||
|
||||
describe("Editor- Test Button widget", () => {
|
||||
|
||||
beforeEach(() => {
|
||||
cy.appUILogin();
|
||||
cy.createApp();
|
||||
|
|
@ -48,7 +44,7 @@ describe("Editor- Test Button widget", () => {
|
|||
cy.renameApp(data.appName);
|
||||
|
||||
openEditorSidebar(buttonText.defaultWidgetName);
|
||||
editAndVerifyWidgetName(data.widgetName)
|
||||
editAndVerifyWidgetName(data.widgetName);
|
||||
|
||||
openAccordion(commonWidgetText.accordionProperties);
|
||||
verifyAndModifyParameter(buttonText.buttonTextLabel, data.widgetName);
|
||||
|
|
@ -81,7 +77,7 @@ describe("Editor- Test Button widget", () => {
|
|||
|
||||
verifyLayout(data.widgetName);
|
||||
|
||||
cy.get(commonWidgetSelector.changeLayoutButton).click();
|
||||
cy.get(commonWidgetSelector.changeLayoutToDesktopButton).click();
|
||||
cy.get(
|
||||
commonWidgetSelector.parameterTogglebutton(
|
||||
commonWidgetText.parameterShowOnDesktop
|
||||
|
|
@ -124,7 +120,10 @@ describe("Editor- Test Button widget", () => {
|
|||
commonWidgetSelector.parameterFxButton(buttonText.backgroundColor)
|
||||
).click();
|
||||
|
||||
selectColourFromColourPicker(buttonText.backgroundColor, data.backgroundColor);
|
||||
selectColourFromColourPicker(
|
||||
buttonText.backgroundColor,
|
||||
data.backgroundColor
|
||||
);
|
||||
|
||||
verifyWidgetColorCss(
|
||||
buttonText.defaultWidgetName,
|
||||
|
|
@ -146,7 +145,7 @@ describe("Editor- Test Button widget", () => {
|
|||
commonWidgetSelector.parameterFxButton(buttonText.textColor)
|
||||
).click();
|
||||
|
||||
selectColourFromColourPicker(buttonText.textColor, data.textColor);
|
||||
selectColourFromColourPicker(buttonText.textColor, data.textColor, 1);
|
||||
|
||||
verifyWidgetColorCss(buttonText.defaultWidgetName, "color", data.textColor);
|
||||
|
||||
|
|
@ -164,7 +163,7 @@ describe("Editor- Test Button widget", () => {
|
|||
commonWidgetSelector.parameterFxButton(buttonText.loaderColor)
|
||||
).click();
|
||||
|
||||
selectColourFromColourPicker(buttonText.loaderColor, data.loaderColor);
|
||||
selectColourFromColourPicker(buttonText.loaderColor, data.loaderColor, 2);
|
||||
|
||||
verifyLoaderColor(buttonText.defaultWidgetName, data.loaderColor);
|
||||
|
||||
|
|
@ -213,7 +212,13 @@ describe("Editor- Test Button widget", () => {
|
|||
cy.get(commonWidgetSelector.buttonStylesEditorSideBar).click();
|
||||
|
||||
data.colourHex = fake.randomRgbaHex;
|
||||
verifyStylesGeneralAccordion(buttonText.defaultWidgetName, data.boxShadowParam, data.colourHex, data.boxShadowColor);
|
||||
verifyStylesGeneralAccordion(
|
||||
buttonText.defaultWidgetName,
|
||||
data.boxShadowParam,
|
||||
data.colourHex,
|
||||
data.boxShadowColor,
|
||||
4
|
||||
);
|
||||
|
||||
cy.get(commonSelectors.editorPageLogo).click();
|
||||
cy.deleteApp(data.appName);
|
||||
|
|
@ -237,26 +242,32 @@ describe("Editor- Test Button widget", () => {
|
|||
openEditorSidebar(buttonText.defaultWidgetName);
|
||||
verifyAndModifyParameter(buttonText.buttonTextLabel, data.widgetName);
|
||||
|
||||
openAccordion(commonWidgetText.accordionEvents);
|
||||
openAccordion(commonWidgetText.accordionEvents);
|
||||
addDefaultEventHandler(data.alertMessage);
|
||||
|
||||
verifyPropertiesGeneralAccordion(buttonText.defaultWidgetName, data.tooltipText);
|
||||
verifyPropertiesGeneralAccordion(
|
||||
buttonText.defaultWidgetName,
|
||||
data.tooltipText
|
||||
);
|
||||
|
||||
openEditorSidebar(buttonText.defaultWidgetName);
|
||||
cy.get(commonWidgetSelector.buttonStylesEditorSideBar).click();
|
||||
selectColourFromColourPicker(buttonText.backgroundColor, data.backgroundColor);
|
||||
|
||||
cy.get(commonWidgetSelector.buttonCloseEditorSideBar).click();
|
||||
selectColourFromColourPicker(
|
||||
buttonText.backgroundColor,
|
||||
data.backgroundColor
|
||||
);
|
||||
|
||||
cy.forceClickOnCanvas();
|
||||
openEditorSidebar(buttonText.defaultWidgetName);
|
||||
cy.get(commonWidgetSelector.buttonStylesEditorSideBar).click();
|
||||
selectColourFromColourPicker(buttonText.textColor, data.textColor);
|
||||
selectColourFromColourPicker(buttonText.textColor, data.textColor, 1);
|
||||
|
||||
cy.get(commonWidgetSelector.buttonCloseEditorSideBar).click();
|
||||
cy.forceClickOnCanvas();
|
||||
openEditorSidebar(buttonText.defaultWidgetName);
|
||||
cy.get(commonWidgetSelector.buttonStylesEditorSideBar).click();
|
||||
selectColourFromColourPicker(buttonText.loaderColor, data.loaderColor);
|
||||
selectColourFromColourPicker(buttonText.loaderColor, data.loaderColor, 2);
|
||||
|
||||
cy.get(commonWidgetSelector.buttonCloseEditorSideBar).click();
|
||||
cy.forceClickOnCanvas();
|
||||
openEditorSidebar(buttonText.defaultWidgetName);
|
||||
cy.get(commonWidgetSelector.buttonStylesEditorSideBar).click();
|
||||
|
||||
|
|
@ -269,9 +280,18 @@ describe("Editor- Test Button widget", () => {
|
|||
.clear()
|
||||
.type(buttonText.borderRadiusInput);
|
||||
|
||||
verifyStylesGeneralAccordion(buttonText.defaultWidgetName, data.boxShadowParam, data.colourHex, data.boxShadowColor);
|
||||
verifyStylesGeneralAccordion(
|
||||
buttonText.defaultWidgetName,
|
||||
data.boxShadowParam,
|
||||
data.colourHex,
|
||||
data.boxShadowColor,
|
||||
4
|
||||
);
|
||||
|
||||
verifyControlComponentAction(buttonText.defaultWidgetName, data.customMessage);
|
||||
verifyControlComponentAction(
|
||||
buttonText.defaultWidgetName,
|
||||
data.customMessage
|
||||
);
|
||||
|
||||
cy.waitForAutoSave();
|
||||
cy.openInCurrentTab(commonWidgetSelector.previewButton);
|
||||
|
|
@ -280,9 +300,11 @@ describe("Editor- Test Button widget", () => {
|
|||
commonWidgetSelector.draggableWidget(buttonText.defaultWidgetName)
|
||||
).verifyVisibleElement("have.text", data.widgetName);
|
||||
|
||||
cy.get(commonWidgetSelector.draggableWidget(buttonText.defaultWidgetName)).click();
|
||||
cy.get(
|
||||
commonWidgetSelector.draggableWidget(buttonText.defaultWidgetName)
|
||||
).click();
|
||||
cy.verifyToastMessage(commonSelectors.toastMessage, data.alertMessage);
|
||||
cy.get(commonWidgetSelector.draggableWidget('textinput1')).should(
|
||||
cy.get(commonWidgetSelector.draggableWidget("textinput1")).should(
|
||||
"have.value",
|
||||
data.customMessage
|
||||
);
|
||||
|
|
@ -292,17 +314,23 @@ describe("Editor- Test Button widget", () => {
|
|||
data.tooltipText
|
||||
);
|
||||
|
||||
verifyWidgetColorCss(buttonText.defaultWidgetName, "background-color", data.backgroundColor);
|
||||
verifyWidgetColorCss(
|
||||
buttonText.defaultWidgetName,
|
||||
"background-color",
|
||||
data.backgroundColor
|
||||
);
|
||||
verifyWidgetColorCss(buttonText.defaultWidgetName, "color", data.textColor);
|
||||
verifyLoaderColor(buttonText.defaultWidgetName, data.loaderColor);
|
||||
|
||||
cy.get(commonWidgetSelector.draggableWidget(buttonText.defaultWidgetName)).should(
|
||||
"have.css",
|
||||
"border-radius",
|
||||
"20px"
|
||||
);
|
||||
cy.get(
|
||||
commonWidgetSelector.draggableWidget(buttonText.defaultWidgetName)
|
||||
).should("have.css", "border-radius", "20px");
|
||||
|
||||
verifyBoxShadowCss(buttonText.defaultWidgetName, data.boxShadowColor, data.boxShadowParam);
|
||||
verifyBoxShadowCss(
|
||||
buttonText.defaultWidgetName,
|
||||
data.boxShadowColor,
|
||||
data.boxShadowParam
|
||||
);
|
||||
|
||||
cy.get(commonSelectors.viewerPageLogo).click();
|
||||
cy.deleteApp(data.appName);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,604 @@
|
|||
import { commonWidgetSelector, commonSelectors } from "Selectors/common";
|
||||
import { fake } from "Fixtures/fake";
|
||||
import { tableText } from "Texts/table";
|
||||
import { tableSelector } from "Selectors/table";
|
||||
import {
|
||||
verifyComponent,
|
||||
deleteComponentAndVerify,
|
||||
verifyComponentWithOutLabel
|
||||
} from "Support/utils/basicComponents";
|
||||
import {
|
||||
openAccordion,
|
||||
verifyAndModifyParameter,
|
||||
openEditorSidebar,
|
||||
verifyAndModifyToggleFx,
|
||||
addDefaultEventHandler,
|
||||
addAndVerifyTooltip,
|
||||
editAndVerifyWidgetName,
|
||||
verifyComponentValueFromInspector,
|
||||
fillBoxShadowParams,
|
||||
selectColourFromColourPicker,
|
||||
addTextWidgetToVerifyValue,
|
||||
verifyBoxShadowCss,
|
||||
verifyTooltip,
|
||||
verifyWidgetText,
|
||||
closeAccordions,
|
||||
} from "Support/utils/commonWidget";
|
||||
import {
|
||||
commonText,
|
||||
commonWidgetText,
|
||||
codeMirrorInputLabel,
|
||||
} from "Texts/common";
|
||||
|
||||
describe("Basic components", () => {
|
||||
const data = {};
|
||||
beforeEach(() => {
|
||||
data.appName = `${fake.companyName}-App`;
|
||||
cy.appUILogin();
|
||||
cy.createApp();
|
||||
cy.modifyCanvasSize(900, 900);
|
||||
cy.renameApp(data.appName);
|
||||
});
|
||||
|
||||
it("Should verify Toggle switch", () => {
|
||||
cy.dragAndDropWidget("Toggle Switch", 50, 50);
|
||||
verifyComponent("toggleswitch1");
|
||||
|
||||
cy.resizeWidget("toggleswitch1", 850, 600);
|
||||
|
||||
openEditorSidebar("toggleswitch1");
|
||||
editAndVerifyWidgetName("toggleswitch2");
|
||||
|
||||
verifyAndModifyParameter(commonWidgetText.parameterLabel, "label");
|
||||
cy.waitForAutoSave();
|
||||
|
||||
cy.openInCurrentTab(commonWidgetSelector.previewButton);
|
||||
verifyComponent("toggleswitch2");
|
||||
|
||||
cy.go("back");
|
||||
deleteComponentAndVerify("toggleswitch2");
|
||||
cy.get(commonSelectors.editorPageLogo).click();
|
||||
|
||||
cy.deleteApp(data.appName);
|
||||
});
|
||||
|
||||
it("Should verify Checkbox", () => {
|
||||
cy.dragAndDropWidget("Checkbox", 50, 50);
|
||||
cy.resizeWidget("checkbox1", 100, 200);
|
||||
cy.forceClickOnCanvas();
|
||||
verifyComponent("checkbox1");
|
||||
|
||||
cy.resizeWidget("checkbox1", 850, 600);
|
||||
|
||||
openEditorSidebar("checkbox1");
|
||||
editAndVerifyWidgetName("checkbox2");
|
||||
|
||||
verifyAndModifyParameter(commonWidgetText.parameterLabel, "label");
|
||||
cy.forceClickOnCanvas();
|
||||
cy.get('[data-cy="draggable-widget-checkbox2"] .form-check-label').should(
|
||||
"have.text",
|
||||
"label"
|
||||
);
|
||||
cy.waitForAutoSave();
|
||||
|
||||
cy.openInCurrentTab(commonWidgetSelector.previewButton);
|
||||
verifyComponent("checkbox2");
|
||||
|
||||
cy.go("back");
|
||||
deleteComponentAndVerify("checkbox2");
|
||||
cy.get(commonSelectors.editorPageLogo).click();
|
||||
|
||||
cy.deleteApp(data.appName);
|
||||
});
|
||||
|
||||
it("Should verify Radio Button", () => {
|
||||
cy.dragAndDropWidget("Radio Button", 50, 50);
|
||||
// cy.resizeWidget("radiobutton1", 100, 200);
|
||||
cy.forceClickOnCanvas();
|
||||
verifyComponent("radiobutton1");
|
||||
|
||||
cy.resizeWidget("radiobutton1", 850, 600);
|
||||
|
||||
openEditorSidebar("radiobutton1");
|
||||
editAndVerifyWidgetName("radiobutton2");
|
||||
|
||||
verifyAndModifyParameter(commonWidgetText.parameterLabel, "label");
|
||||
cy.forceClickOnCanvas();
|
||||
cy.waitForAutoSave();
|
||||
cy.get('[data-cy="draggable-widget-radiobutton2"] > .col-auto').should(
|
||||
"have.text",
|
||||
"label"
|
||||
);
|
||||
|
||||
cy.openInCurrentTab(commonWidgetSelector.previewButton);
|
||||
verifyComponent("radiobutton2");
|
||||
|
||||
cy.go("back");
|
||||
deleteComponentAndVerify("radiobutton2");
|
||||
cy.get(commonSelectors.editorPageLogo).click();
|
||||
|
||||
cy.deleteApp(data.appName);
|
||||
});
|
||||
it("Should verify Dropdown", () => {
|
||||
cy.dragAndDropWidget("Dropdown", 50, 50);
|
||||
// cy.resizeWidget("radiobutton1", 100, 200);
|
||||
cy.forceClickOnCanvas();
|
||||
verifyComponent("dropdown1");
|
||||
|
||||
cy.resizeWidget("dropdown1", 850, 600);
|
||||
|
||||
openEditorSidebar("dropdown1");
|
||||
editAndVerifyWidgetName("dropdown2");
|
||||
|
||||
verifyAndModifyParameter(commonWidgetText.parameterLabel, "label");
|
||||
cy.forceClickOnCanvas();
|
||||
cy.waitForAutoSave();
|
||||
cy.get('[data-cy="draggable-widget-dropdown2"] > .col-auto').should(
|
||||
"have.text",
|
||||
"label"
|
||||
);
|
||||
|
||||
cy.openInCurrentTab(commonWidgetSelector.previewButton);
|
||||
verifyComponent("dropdown2");
|
||||
|
||||
cy.go("back");
|
||||
deleteComponentAndVerify("dropdown2");
|
||||
cy.get(commonSelectors.editorPageLogo).click();
|
||||
|
||||
cy.deleteApp(data.appName);
|
||||
});
|
||||
//pending
|
||||
it("Should verify Rating", () => {
|
||||
cy.dragAndDropWidget("Rating", 300, 300);
|
||||
cy.get('[data-cy="draggable-widget-starrating1"]').click({ force: true });
|
||||
// cy.resizeWidget("starrating1", 300, 500);
|
||||
cy.forceClickOnCanvas();
|
||||
verifyComponent("starrating1");
|
||||
|
||||
cy.resizeWidget("starrating1", 850, 600);
|
||||
|
||||
openEditorSidebar("starrating1");
|
||||
editAndVerifyWidgetName("starrating2");
|
||||
|
||||
verifyAndModifyParameter(commonWidgetText.parameterLabel, "label");
|
||||
cy.forceClickOnCanvas();
|
||||
cy.waitForAutoSave();
|
||||
cy.get('[data-cy="draggable-widget-starrating2"] > .col-auto').should(
|
||||
"have.text",
|
||||
"label"
|
||||
);
|
||||
|
||||
cy.openInCurrentTab(commonWidgetSelector.previewButton);
|
||||
verifyComponent("starrating2");
|
||||
|
||||
cy.go("back");
|
||||
deleteComponentAndVerify("starrating2");
|
||||
cy.get(commonSelectors.editorPageLogo).click();
|
||||
|
||||
cy.deleteApp(data.appName);
|
||||
});
|
||||
|
||||
it("Should verify Button Group", () => {
|
||||
cy.dragAndDropWidget("Button Group", 300, 300);
|
||||
cy.forceClickOnCanvas();
|
||||
verifyComponent("buttongroup1");
|
||||
|
||||
cy.resizeWidget("buttongroup1", 850, 600);
|
||||
|
||||
openEditorSidebar("buttongroup1");
|
||||
editAndVerifyWidgetName("buttongroup2");
|
||||
|
||||
verifyAndModifyParameter(commonWidgetText.parameterLabel, "label");
|
||||
cy.forceClickOnCanvas();
|
||||
cy.waitForAutoSave();
|
||||
cy.get(
|
||||
'[data-cy="draggable-widget-buttongroup2"] > .widget-buttongroup-label'
|
||||
).should("have.text", "label");
|
||||
|
||||
cy.openInCurrentTab(commonWidgetSelector.previewButton);
|
||||
verifyComponent("buttongroup2");
|
||||
|
||||
cy.go("back");
|
||||
deleteComponentAndVerify("buttongroup2");
|
||||
cy.get(commonSelectors.editorPageLogo).click();
|
||||
|
||||
cy.deleteApp(data.appName);
|
||||
});
|
||||
|
||||
it("Should verify Calendar", () => {
|
||||
cy.dragAndDropWidget("Calendar", 50, 50);
|
||||
cy.get('[data-tip="Hide query editor"]').click();
|
||||
cy.get('[data-cy="draggable-widget-calendar1"]').click({ force: true });
|
||||
cy.forceClickOnCanvas();
|
||||
verifyComponent("calendar1");
|
||||
|
||||
cy.resizeWidget("calendar1", 850, 600);
|
||||
|
||||
openEditorSidebar("calendar1");
|
||||
editAndVerifyWidgetName("calendar2");
|
||||
|
||||
cy.waitForAutoSave();
|
||||
cy.openInCurrentTab(commonWidgetSelector.previewButton);
|
||||
verifyComponent("calendar2");
|
||||
|
||||
cy.go("back");
|
||||
deleteComponentAndVerify("calendar2");
|
||||
cy.get(commonSelectors.editorPageLogo).click();
|
||||
|
||||
cy.deleteApp(data.appName);
|
||||
});
|
||||
|
||||
it("Should verify Chart", () => {
|
||||
cy.dragAndDropWidget("Chart", 50, 50);
|
||||
cy.get('[data-cy="draggable-widget-chart1"]').click({ force: true });
|
||||
cy.forceClickOnCanvas();
|
||||
verifyComponent("chart1");
|
||||
|
||||
cy.resizeWidget("chart1", 850, 600);
|
||||
|
||||
openEditorSidebar("chart1");
|
||||
editAndVerifyWidgetName("chart2", ["Chart data", "Properties"]);
|
||||
|
||||
verifyAndModifyParameter("Title", "label");
|
||||
cy.forceClickOnCanvas();
|
||||
cy.waitForAutoSave();
|
||||
cy.get('[data-cy="draggable-widget-chart2"]').should(
|
||||
"contain.text",
|
||||
"label"
|
||||
);
|
||||
|
||||
cy.openInCurrentTab(commonWidgetSelector.previewButton);
|
||||
verifyComponent("chart2");
|
||||
|
||||
cy.go("back");
|
||||
deleteComponentAndVerify("chart2");
|
||||
cy.get(commonSelectors.editorPageLogo).click();
|
||||
|
||||
cy.deleteApp(data.appName);
|
||||
});
|
||||
|
||||
it("Should verify Circular Progress Bar", () => {
|
||||
cy.dragAndDropWidget("Circular Progressbar", 300, 300);
|
||||
cy.forceClickOnCanvas();
|
||||
verifyComponent("circularprogressbar1");
|
||||
|
||||
cy.resizeWidget("circularprogressbar1", 850, 600);
|
||||
|
||||
openEditorSidebar("circularprogressbar1");
|
||||
editAndVerifyWidgetName("circularprogressbar2");
|
||||
|
||||
cy.forceClickOnCanvas();
|
||||
cy.waitForAutoSave();
|
||||
|
||||
cy.openInCurrentTab(commonWidgetSelector.previewButton);
|
||||
verifyComponent("circularprogressbar2");
|
||||
|
||||
cy.go("back");
|
||||
deleteComponentAndVerify("circularprogressbar2");
|
||||
cy.get(commonSelectors.editorPageLogo).click();
|
||||
|
||||
cy.deleteApp(data.appName);
|
||||
});
|
||||
|
||||
it("Should verify Code Editor", () => {
|
||||
cy.dragAndDropWidget("Code Editor", 300, 300);
|
||||
cy.get('[data-cy="draggable-widget-codeeditor1"]').click({ force: true });
|
||||
cy.forceClickOnCanvas();
|
||||
verifyComponent("codeeditor1");
|
||||
|
||||
cy.resizeWidget("codeeditor1", 850, 600);
|
||||
|
||||
openEditorSidebar("codeeditor1");
|
||||
editAndVerifyWidgetName("codeeditor2");
|
||||
cy.forceClickOnCanvas();
|
||||
cy.waitForAutoSave();
|
||||
|
||||
cy.openInCurrentTab(commonWidgetSelector.previewButton);
|
||||
verifyComponent("codeeditor2");
|
||||
|
||||
cy.go("back");
|
||||
deleteComponentAndVerify("codeeditor2");
|
||||
cy.get(commonSelectors.editorPageLogo).click();
|
||||
|
||||
cy.deleteApp(data.appName);
|
||||
});
|
||||
|
||||
it("Should verify Color Picker", () => {
|
||||
cy.dragAndDropWidget("Color Picker", 300, 300);
|
||||
cy.get('[data-cy="draggable-widget-colorpicker1"]').click({ force: true });
|
||||
cy.forceClickOnCanvas();
|
||||
verifyComponent("colorpicker1");
|
||||
|
||||
cy.resizeWidget("colorpicker1", 850, 600);
|
||||
|
||||
openEditorSidebar("colorpicker1");
|
||||
editAndVerifyWidgetName("colorpicker2");
|
||||
|
||||
cy.forceClickOnCanvas();
|
||||
cy.waitForAutoSave();
|
||||
|
||||
cy.openInCurrentTab(commonWidgetSelector.previewButton);
|
||||
verifyComponent("colorpicker2");
|
||||
|
||||
cy.go("back");
|
||||
deleteComponentAndVerify("colorpicker2");
|
||||
cy.get(commonSelectors.editorPageLogo).click();
|
||||
|
||||
cy.deleteApp(data.appName);
|
||||
});
|
||||
//needed fix
|
||||
it.skip("Should verify Custom Component", () => {
|
||||
cy.dragAndDropWidget("Custom Component", 50, 50);
|
||||
cy.get('[data-cy="draggable-widget-customcomponent1"]').click({ force: true });
|
||||
cy.forceClickOnCanvas();
|
||||
verifyComponent("customcomponent1");
|
||||
openEditorSidebar("customcomponent1");
|
||||
|
||||
// editAndVerifyWidgetName("customcomponent2", ["Code"]);
|
||||
closeAccordions(["Code"]);
|
||||
cy.get(commonWidgetSelector.WidgetNameInputField).type("{selectAll}{backspace}customcomponent2", {delay:30});
|
||||
cy.forceClickOnCanvas()
|
||||
|
||||
cy.get(commonWidgetSelector.draggableWidget(name)).trigger("mouseover");
|
||||
cy.get(commonWidgetSelector.widgetConfigHandle(name))
|
||||
.click()
|
||||
.should("have.text", name);
|
||||
|
||||
cy.resizeWidget("customcomponent1", 850, 600);
|
||||
|
||||
openEditorSidebar("customcomponent1");
|
||||
cy.forceClickOnCanvas();
|
||||
cy.waitForAutoSave();
|
||||
|
||||
cy.openInCurrentTab(commonWidgetSelector.previewButton);
|
||||
verifyComponent("customcomponent2", ["Code"]);
|
||||
|
||||
cy.go("back");
|
||||
deleteComponentAndVerify("customcomponent2");
|
||||
cy.get(commonSelectors.editorPageLogo).click();
|
||||
|
||||
cy.deleteApp(data.appName);
|
||||
});
|
||||
|
||||
it("Should verify Container", () => {
|
||||
cy.dragAndDropWidget("Container", 50, 50);
|
||||
cy.forceClickOnCanvas();
|
||||
verifyComponent("container1");
|
||||
|
||||
cy.resizeWidget("container1", 850, 600);
|
||||
|
||||
openEditorSidebar("container1");
|
||||
editAndVerifyWidgetName("container2", ["Layout"]);
|
||||
|
||||
cy.forceClickOnCanvas();
|
||||
cy.waitForAutoSave();
|
||||
|
||||
cy.openInCurrentTab(commonWidgetSelector.previewButton);
|
||||
verifyComponent("container2", ["Layout"]);
|
||||
|
||||
cy.go("back");
|
||||
deleteComponentAndVerify("container2");
|
||||
cy.get(commonSelectors.editorPageLogo).click();
|
||||
|
||||
cy.deleteApp(data.appName);
|
||||
});
|
||||
|
||||
it("Should verify Date-Range Picker", () => {
|
||||
cy.dragAndDropWidget("Range Picker", 300, 300);
|
||||
|
||||
cy.forceClickOnCanvas();
|
||||
verifyComponent("daterangepicker1");
|
||||
|
||||
cy.resizeWidget("daterangepicker1", 850, 600);
|
||||
|
||||
openEditorSidebar("daterangepicker1");
|
||||
editAndVerifyWidgetName("daterangepicker2");
|
||||
|
||||
cy.forceClickOnCanvas();
|
||||
cy.waitForAutoSave();
|
||||
|
||||
cy.openInCurrentTab(commonWidgetSelector.previewButton);
|
||||
verifyComponent("daterangepicker2");
|
||||
|
||||
cy.go("back");
|
||||
deleteComponentAndVerify("daterangepicker2");
|
||||
cy.get(commonSelectors.editorPageLogo).click();
|
||||
|
||||
cy.deleteApp(data.appName);
|
||||
});
|
||||
//visible issue
|
||||
it.skip("Should verify Divider", () => {
|
||||
verifyComponentWithOutLabel("Divider", "divider1", "divider2", data.appName)
|
||||
});
|
||||
|
||||
it("Should verify File Picker", () => {
|
||||
verifyComponentWithOutLabel("File Picker", "filepicker1", "filepicker2", data.appName)
|
||||
});
|
||||
|
||||
it("Should verify Form", () => {
|
||||
cy.dragAndDropWidget("Form", 50, 50);
|
||||
verifyComponent("form1");
|
||||
|
||||
cy.resizeWidget("form1", 850, 600);
|
||||
|
||||
openEditorSidebar("form1");
|
||||
editAndVerifyWidgetName("form2");
|
||||
|
||||
cy.waitForAutoSave();
|
||||
|
||||
cy.openInCurrentTab(commonWidgetSelector.previewButton);
|
||||
verifyComponent("form2");
|
||||
|
||||
cy.go("back");
|
||||
deleteComponentAndVerify("form2");
|
||||
cy.get(commonSelectors.editorPageLogo).click();
|
||||
|
||||
cy.deleteApp(data.appName);
|
||||
});
|
||||
|
||||
it("Should verify HTML", () => {
|
||||
cy.dragAndDropWidget("HTML Viewe", 50, 50, "HTML Viewer"); // search logic WIP
|
||||
verifyComponent("html1");
|
||||
|
||||
cy.resizeWidget("html1", 850, 600);
|
||||
|
||||
openEditorSidebar("html1");
|
||||
editAndVerifyWidgetName("html2");
|
||||
|
||||
cy.waitForAutoSave();
|
||||
|
||||
cy.openInCurrentTab(commonWidgetSelector.previewButton);
|
||||
verifyComponent("html2");
|
||||
|
||||
cy.go("back");
|
||||
deleteComponentAndVerify("html2");
|
||||
cy.get(commonSelectors.editorPageLogo).click();
|
||||
|
||||
cy.deleteApp(data.appName);
|
||||
});
|
||||
|
||||
it("Should verify Icon", () => {
|
||||
verifyComponentWithOutLabel("Icon", "icon1", "icon2", data.appName)
|
||||
});
|
||||
|
||||
it("Should verify Iframe", () => {
|
||||
verifyComponentWithOutLabel("Iframe", "iframe1", "iframe2", data.appName)
|
||||
});
|
||||
|
||||
it("Should verify Kamban", () => {
|
||||
verifyComponentWithOutLabel("Kanban Board", "kanbanboard1", "kanbanboard2", data.appName) });
|
||||
|
||||
it("Should verify Link", () => {
|
||||
verifyComponentWithOutLabel("Link", "link1", "link2", data.appName)
|
||||
});
|
||||
|
||||
it("Should verify Map", () => {
|
||||
cy.dragAndDropWidget("Map", 50, 50);
|
||||
cy.get("body").then($body => {
|
||||
if ($body.find(".dismissButton").length > 0) {
|
||||
cy.get('.dismissButton').click();
|
||||
}
|
||||
})
|
||||
|
||||
verifyComponent("map1");
|
||||
|
||||
cy.resizeWidget("map1", 850, 600);
|
||||
|
||||
openEditorSidebar("map1");
|
||||
editAndVerifyWidgetName("map2");
|
||||
|
||||
cy.waitForAutoSave();
|
||||
|
||||
cy.openInCurrentTab(commonWidgetSelector.previewButton);
|
||||
verifyComponent("map2");
|
||||
|
||||
cy.go("back");
|
||||
deleteComponentAndVerify("map2");
|
||||
cy.get(commonSelectors.editorPageLogo).click();
|
||||
|
||||
cy.deleteApp(data.appName);
|
||||
});
|
||||
|
||||
it("Should verify Modal", () => {
|
||||
verifyComponentWithOutLabel("Modal", "modal1", "modal2", data.appName)
|
||||
});
|
||||
|
||||
it("Should verify PDF", () => {
|
||||
cy.dragAndDropWidget("PDF", 50, 50);
|
||||
cy.get('[data-tip="Hide query editor"]').click();
|
||||
verifyComponent("pdf1");
|
||||
|
||||
cy.resizeWidget("pdf1", 850, 600);
|
||||
|
||||
openEditorSidebar("pdf1");
|
||||
editAndVerifyWidgetName("pdf2");
|
||||
|
||||
cy.waitForAutoSave();
|
||||
|
||||
cy.openInCurrentTab(commonWidgetSelector.previewButton);
|
||||
verifyComponent("pdf2");
|
||||
|
||||
cy.go("back");
|
||||
deleteComponentAndVerify("pdf2");
|
||||
cy.get(commonSelectors.editorPageLogo).click();
|
||||
|
||||
cy.deleteApp(data.appName);
|
||||
});
|
||||
|
||||
it("Should verify Pagination", () => {
|
||||
verifyComponentWithOutLabel("Pagination", "pagination1", "pagination2", data.appName)
|
||||
});
|
||||
|
||||
it("Should verify QR Scanner", () => {
|
||||
verifyComponentWithOutLabel("QR Scanner", "qrscanner1", "qrscanner2", data.appName)
|
||||
});
|
||||
|
||||
it("Should verify Range Slider", () => {
|
||||
verifyComponentWithOutLabel("Range Slider", "rangeslider1", "rangeslider2", data.appName)
|
||||
});
|
||||
|
||||
it("Should verify Rich Text Editor", () => {
|
||||
verifyComponentWithOutLabel("Text Editor", "richtexteditor1", "richtexteditor2", data.appName)
|
||||
});
|
||||
|
||||
it("Should verify Spinner", () => {
|
||||
verifyComponentWithOutLabel("Spinner", "spinner1", "spinner2", data.appName);
|
||||
});
|
||||
|
||||
it("Should verify Statistics", () => {
|
||||
verifyComponentWithOutLabel("Statistics", "statistics1", "statistics2", data.appName)
|
||||
});
|
||||
|
||||
it("Should verify Steps", () => {
|
||||
verifyComponentWithOutLabel("Steps", "steps1", "steps2", data.appName)
|
||||
});
|
||||
|
||||
it("Should verify SVG Image", () => {
|
||||
verifyComponentWithOutLabel("SVG Image", "svgimage1", "svgimage2", data.appName)
|
||||
});
|
||||
|
||||
it("Should verify Tabs", () => {
|
||||
cy.dragAndDropWidget("Tabs", 50, 50);
|
||||
verifyComponent("tabs1");
|
||||
deleteComponentAndVerify("image1");
|
||||
|
||||
cy.resizeWidget("tabs1", 850, 600);
|
||||
|
||||
openEditorSidebar("tabs1");
|
||||
editAndVerifyWidgetName("tabs2");
|
||||
|
||||
cy.waitForAutoSave();
|
||||
|
||||
cy.openInCurrentTab(commonWidgetSelector.previewButton);
|
||||
verifyComponent("tabs2");
|
||||
|
||||
cy.go("back");
|
||||
deleteComponentAndVerify("tabs2");
|
||||
cy.get(commonSelectors.editorPageLogo).click();
|
||||
|
||||
cy.deleteApp(data.appName);
|
||||
});
|
||||
|
||||
it("Should verify Tags", () => {
|
||||
verifyComponentWithOutLabel("Tags", "tags1", "tags2", data.appName)
|
||||
});
|
||||
|
||||
it("Should verify Textarea", () => {
|
||||
verifyComponentWithOutLabel("Textarea", "textarea1", "textarea2", data.appName)
|
||||
});
|
||||
|
||||
it("Should verify Timeline", () => {
|
||||
verifyComponentWithOutLabel("Timeline", "timeline1", "timeline2", data.appName)
|
||||
});
|
||||
it("Should verify Timer", () => {
|
||||
verifyComponentWithOutLabel("Timer", "timer1", "timer2", data.appName)
|
||||
});
|
||||
|
||||
it("Should verify Tree Select", () => {
|
||||
verifyComponentWithOutLabel("Tree Select", "treeselect1", "treeselect2", data.appName)
|
||||
});
|
||||
|
||||
it("Should verify Vertical Divider", () => {
|
||||
verifyComponentWithOutLabel("Vertical Divider", "verticaldivider1", "verticaldivider2", data.appName)
|
||||
});
|
||||
});
|
||||
|
|
@ -66,7 +66,7 @@ describe("Date Picker widget", () => {
|
|||
verifyAndModifyParameter(datePickerText.labelformat, "DD/MM/YY");
|
||||
cy.get(commonWidgetSelector.buttonCloseEditorSideBar).click();
|
||||
verifyDate(data.widgetName, data.date, "DD/MM/YY");
|
||||
verifyComponentValueFromInspector(data.widgetName, data.date, "opened");
|
||||
verifyComponentValueFromInspector(data.widgetName, data.date);
|
||||
cy.get(commonSelectors.canvas).click({ force: true });
|
||||
|
||||
openEditorSidebar(data.widgetName);
|
||||
|
|
@ -156,14 +156,14 @@ describe("Date Picker widget", () => {
|
|||
"not.exist"
|
||||
);
|
||||
|
||||
verifyAndModifyToggleFx(
|
||||
commonWidgetText.parameterShowOnMobile,
|
||||
commonWidgetText.codeMirrorLabelFalse
|
||||
);
|
||||
cy.get(commonWidgetSelector.changeLayoutButton).click();
|
||||
cy.get(commonWidgetSelector.draggableWidget(data.widgetName)).should(
|
||||
"exist"
|
||||
);
|
||||
// verifyAndModifyToggleFx(
|
||||
// commonWidgetText.parameterShowOnMobile,
|
||||
// commonWidgetText.codeMirrorLabelFalse
|
||||
// );
|
||||
// cy.get(commonWidgetSelector.changeLayoutButton).click();
|
||||
// cy.get(commonWidgetSelector.draggableWidget(data.widgetName)).should(
|
||||
// "exist"
|
||||
// );
|
||||
});
|
||||
|
||||
it("should verify the styles of the date picker widget", () => {
|
||||
|
|
@ -278,7 +278,7 @@ describe("Date Picker widget", () => {
|
|||
commonWidgetText.borderRadiusInput
|
||||
);
|
||||
|
||||
openAccordion(commonWidgetText.accordionGenaral, [], "1");
|
||||
openAccordion(commonWidgetText.accordionGenaral, []);
|
||||
|
||||
cy.get(
|
||||
commonWidgetSelector.stylePicker(commonWidgetText.parameterBoxShadow)
|
||||
|
|
|
|||
|
|
@ -175,14 +175,14 @@ describe("List view widget", () => {
|
|||
"not.exist"
|
||||
);
|
||||
|
||||
verifyAndModifyToggleFx(
|
||||
commonWidgetText.parameterShowOnMobile,
|
||||
commonWidgetText.codeMirrorLabelFalse
|
||||
);
|
||||
cy.get(commonWidgetSelector.changeLayoutButton).click();
|
||||
cy.get(commonWidgetSelector.draggableWidget(data.widgetName)).should(
|
||||
"exist"
|
||||
);
|
||||
// verifyAndModifyToggleFx(
|
||||
// commonWidgetText.parameterShowOnMobile,
|
||||
// commonWidgetText.codeMirrorLabelFalse
|
||||
// );
|
||||
// cy.get(commonWidgetSelector.changeLayoutButton).click();
|
||||
// cy.get(commonWidgetSelector.draggableWidget(data.widgetName)).should(
|
||||
// "exist"
|
||||
// );
|
||||
});
|
||||
|
||||
it("should verify the styles of the list view widget", () => {
|
||||
|
|
@ -230,7 +230,7 @@ describe("List view widget", () => {
|
|||
|
||||
openEditorSidebar(listviewText.defaultWidgetName);
|
||||
cy.get(commonWidgetSelector.buttonStylesEditorSideBar).click();
|
||||
openAccordion(commonWidgetText.accordionGenaral, [], "1");
|
||||
openAccordion(commonWidgetText.accordionGenaral, []);
|
||||
|
||||
verifyAndModifyToggleFx(
|
||||
commonWidgetText.parameterBoxShadow,
|
||||
|
|
@ -246,7 +246,11 @@ describe("List view widget", () => {
|
|||
data.boxShadowParam
|
||||
);
|
||||
|
||||
selectColourFromColourPicker(commonWidgetText.boxShadowColor, data.colour);
|
||||
selectColourFromColourPicker(
|
||||
commonWidgetText.boxShadowColor,
|
||||
data.colour,
|
||||
2
|
||||
);
|
||||
verifyBoxShadowCss(
|
||||
listviewText.defaultWidgetName,
|
||||
data.colour,
|
||||
|
|
@ -368,7 +372,7 @@ describe("List view widget", () => {
|
|||
|
||||
openEditorSidebar(listviewText.defaultWidgetName);
|
||||
cy.get(commonWidgetSelector.buttonStylesEditorSideBar).click();
|
||||
openAccordion(commonWidgetText.accordionGenaral, [], "1");
|
||||
openAccordion(commonWidgetText.accordionGenaral, []);
|
||||
|
||||
verifyAndModifyToggleFx(
|
||||
commonWidgetText.parameterBoxShadow,
|
||||
|
|
@ -381,7 +385,11 @@ describe("List view widget", () => {
|
|||
commonWidgetSelector.boxShadowDefaultParam,
|
||||
data.boxShadowParam
|
||||
);
|
||||
selectColourFromColourPicker(commonWidgetText.boxShadowColor, data.colour);
|
||||
selectColourFromColourPicker(
|
||||
commonWidgetText.boxShadowColor,
|
||||
data.colour,
|
||||
2
|
||||
);
|
||||
|
||||
cy.openInCurrentTab(commonWidgetSelector.previewButton);
|
||||
|
||||
|
|
|
|||
|
|
@ -79,11 +79,7 @@ describe("Multiselect widget", () => {
|
|||
commonWidgetText.labelDefaultValue,
|
||||
codeMirrorInputLabel("[1,2]")
|
||||
);
|
||||
verifyMultipleComponentValuesFromInspector(
|
||||
data.widgetName,
|
||||
[1, 2],
|
||||
"opened"
|
||||
);
|
||||
verifyMultipleComponentValuesFromInspector(data.widgetName, [1, 2]);
|
||||
|
||||
verifyMultiselectHeader(data.widgetName, "one, two");
|
||||
verifyMultiselectStatus(data.widgetName);
|
||||
|
|
@ -96,11 +92,7 @@ describe("Multiselect widget", () => {
|
|||
multiselectText.labelAllItemsSelected
|
||||
);
|
||||
|
||||
verifyMultipleComponentValuesFromInspector(
|
||||
data.widgetName,
|
||||
[1, 2, 3],
|
||||
"opened"
|
||||
);
|
||||
verifyMultipleComponentValuesFromInspector(data.widgetName, [1, 2, 3]);
|
||||
|
||||
openEditorSidebar(data.widgetName);
|
||||
verifyAndModifyParameter(
|
||||
|
|
@ -111,8 +103,7 @@ describe("Multiselect widget", () => {
|
|||
|
||||
verifyMultipleComponentValuesFromInspector(
|
||||
data.widgetName,
|
||||
data.randomLabels,
|
||||
"opened"
|
||||
data.randomLabels
|
||||
);
|
||||
|
||||
openEditorSidebar(data.widgetName);
|
||||
|
|
@ -169,14 +160,14 @@ describe("Multiselect widget", () => {
|
|||
"not.exist"
|
||||
);
|
||||
|
||||
verifyAndModifyToggleFx(
|
||||
commonWidgetText.parameterShowOnMobile,
|
||||
commonWidgetText.codeMirrorLabelFalse
|
||||
);
|
||||
cy.get(commonWidgetSelector.changeLayoutButton).click();
|
||||
cy.get(commonWidgetSelector.draggableWidget(data.widgetName)).should(
|
||||
"exist"
|
||||
);
|
||||
// verifyAndModifyToggleFx(
|
||||
// commonWidgetText.parameterShowOnMobile,
|
||||
// commonWidgetText.codeMirrorLabelFalse
|
||||
// );
|
||||
// cy.get(commonWidgetSelector.changeLayoutButton).click();
|
||||
// cy.get(commonWidgetSelector.draggableWidget(data.widgetName)).should(
|
||||
// "exist"
|
||||
// );
|
||||
});
|
||||
|
||||
it("should verify the styles of the widget", () => {
|
||||
|
|
@ -223,7 +214,7 @@ describe("Multiselect widget", () => {
|
|||
|
||||
openEditorSidebar(multiselectText.defaultWidgetName);
|
||||
cy.get(commonWidgetSelector.buttonStylesEditorSideBar).click();
|
||||
openAccordion(commonWidgetText.accordionGenaral, [], "1");
|
||||
openAccordion(commonWidgetText.accordionGenaral, []);
|
||||
|
||||
verifyAndModifyStylePickerFx(
|
||||
commonWidgetText.parameterBoxShadow,
|
||||
|
|
@ -288,7 +279,7 @@ describe("Multiselect widget", () => {
|
|||
|
||||
openEditorSidebar(data.widgetName);
|
||||
cy.get(commonWidgetSelector.buttonStylesEditorSideBar).click();
|
||||
openAccordion(commonWidgetText.accordionGenaral, [], "1");
|
||||
openAccordion(commonWidgetText.accordionGenaral, []);
|
||||
|
||||
cy.get(
|
||||
commonWidgetSelector.stylePicker(commonWidgetText.parameterBoxShadow)
|
||||
|
|
|
|||
|
|
@ -117,14 +117,14 @@ describe("Number Input", () => {
|
|||
|
||||
verifyPropertiesGeneralAccordion(data.widgetName, data.tooltipText);
|
||||
|
||||
verifyLayout(data.widgetName);
|
||||
// verifyLayout(data.widgetName);
|
||||
|
||||
cy.get(commonWidgetSelector.changeLayoutButton).click();
|
||||
cy.get(
|
||||
commonWidgetSelector.parameterTogglebutton(
|
||||
commonWidgetText.parameterShowOnDesktop
|
||||
)
|
||||
).click();
|
||||
// cy.get(commonWidgetSelector.changeLayoutButton).click();
|
||||
// cy.get(
|
||||
// commonWidgetSelector.parameterTogglebutton(
|
||||
// commonWidgetText.parameterShowOnDesktop
|
||||
// )
|
||||
// ).click();
|
||||
|
||||
cy.get(commonWidgetSelector.widgetDocumentationLink).should(
|
||||
"have.text",
|
||||
|
|
@ -189,7 +189,8 @@ describe("Number Input", () => {
|
|||
numberInputText.defaultWidgetName,
|
||||
data.boxShadowParam,
|
||||
data.colourHex,
|
||||
data.boxShadowColor
|
||||
data.boxShadowColor,
|
||||
3
|
||||
);
|
||||
|
||||
cy.get(commonSelectors.editorPageLogo).click();
|
||||
|
|
@ -245,7 +246,7 @@ describe("Number Input", () => {
|
|||
|
||||
openEditorSidebar(numberInputText.defaultWidgetName);
|
||||
cy.get(commonWidgetSelector.buttonStylesEditorSideBar).click();
|
||||
openAccordion(commonWidgetText.accordionGenaral, [], "1");
|
||||
openAccordion(commonWidgetText.accordionGenaral, []);
|
||||
cy.get(commonWidgetSelector.boxShadowColorPicker).click();
|
||||
|
||||
fillBoxShadowParams(
|
||||
|
|
@ -254,7 +255,8 @@ describe("Number Input", () => {
|
|||
);
|
||||
selectColourFromColourPicker(
|
||||
commonWidgetText.boxShadowColor,
|
||||
data.boxShadowColor
|
||||
data.boxShadowColor,
|
||||
3
|
||||
);
|
||||
addTextWidgetToVerifyValue("components.numberinput1.value");
|
||||
|
||||
|
|
|
|||
|
|
@ -154,14 +154,14 @@ describe("Password Input", () => {
|
|||
cy.get(
|
||||
commonWidgetSelector.accordion(commonWidgetText.accordionValidation)
|
||||
).click();
|
||||
verifyLayout(data.widgetName);
|
||||
// verifyLayout(data.widgetName);
|
||||
|
||||
cy.get(commonWidgetSelector.changeLayoutButton).click();
|
||||
cy.get(
|
||||
commonWidgetSelector.parameterTogglebutton(
|
||||
commonWidgetText.parameterShowOnDesktop
|
||||
)
|
||||
).click();
|
||||
// cy.get(commonWidgetSelector.changeLayoutButton).click();
|
||||
// cy.get(
|
||||
// commonWidgetSelector.parameterTogglebutton(
|
||||
// commonWidgetText.parameterShowOnDesktop
|
||||
// )
|
||||
// ).click();
|
||||
|
||||
cy.get(commonWidgetSelector.widgetDocumentationLink).should(
|
||||
"have.text",
|
||||
|
|
@ -226,7 +226,8 @@ describe("Password Input", () => {
|
|||
passwordInputText.defaultWidgetName,
|
||||
data.boxShadowParam,
|
||||
data.colourHex,
|
||||
data.boxShadowColor
|
||||
data.boxShadowColor,
|
||||
1
|
||||
);
|
||||
|
||||
cy.get(commonSelectors.editorPageLogo).click();
|
||||
|
|
@ -299,7 +300,7 @@ describe("Password Input", () => {
|
|||
|
||||
openEditorSidebar(passwordInputText.defaultWidgetName);
|
||||
cy.get(commonWidgetSelector.buttonStylesEditorSideBar).click();
|
||||
openAccordion(commonWidgetText.accordionGenaral, [], "1");
|
||||
openAccordion(commonWidgetText.accordionGenaral, []);
|
||||
cy.get(commonWidgetSelector.boxShadowColorPicker).click();
|
||||
|
||||
fillBoxShadowParams(
|
||||
|
|
@ -308,7 +309,8 @@ describe("Password Input", () => {
|
|||
);
|
||||
selectColourFromColourPicker(
|
||||
commonWidgetText.boxShadowColor,
|
||||
data.boxShadowColor
|
||||
data.boxShadowColor,
|
||||
1
|
||||
);
|
||||
addTextWidgetToVerifyValue("components.passwordinput1.value");
|
||||
cy.waitForAutoSave();
|
||||
|
|
@ -335,6 +337,7 @@ describe("Password Input", () => {
|
|||
cy.get(
|
||||
commonWidgetSelector.draggableWidget(commonWidgetText.text1)
|
||||
).verifyVisibleElement("have.text", "t");
|
||||
cy.forceClickOnCanvas();
|
||||
cy.get(
|
||||
commonWidgetSelector.validationFeedbackMessage(
|
||||
passwordInputText.defaultWidgetName
|
||||
|
|
|
|||
|
|
@ -173,7 +173,7 @@ describe("Text Input", () => {
|
|||
).click();
|
||||
verifyLayout(data.widgetName);
|
||||
|
||||
cy.get(commonWidgetSelector.changeLayoutButton).click();
|
||||
cy.get(commonWidgetSelector.changeLayoutToDesktopButton).click();
|
||||
cy.get(
|
||||
commonWidgetSelector.parameterTogglebutton(
|
||||
commonWidgetText.parameterShowOnDesktop
|
||||
|
|
@ -245,7 +245,8 @@ describe("Text Input", () => {
|
|||
textInputText.defaultWidgetName,
|
||||
data.boxShadowParam,
|
||||
data.colourHex,
|
||||
data.boxShadowColor
|
||||
data.boxShadowColor,
|
||||
4
|
||||
);
|
||||
|
||||
cy.get(commonSelectors.editorPageLogo).click();
|
||||
|
|
@ -321,7 +322,8 @@ describe("Text Input", () => {
|
|||
textInputText.defaultWidgetName,
|
||||
data.boxShadowParam,
|
||||
data.colourHex,
|
||||
data.boxShadowColor
|
||||
data.boxShadowColor,
|
||||
4
|
||||
);
|
||||
|
||||
cy.waitForAutoSave();
|
||||
|
|
|
|||
|
|
@ -1,12 +0,0 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"paths": {
|
||||
"Texts/*": [
|
||||
"./constants/texts/*"
|
||||
],
|
||||
"Selectors/*": [
|
||||
"./constants/selectors/*"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,18 +1,16 @@
|
|||
import { commonSelectors, commonWidgetSelector } from "Selectors/common";
|
||||
import { dashboardSelector } from "Selectors/dashboard";
|
||||
import { loginSelectors } from "Selectors/login";
|
||||
import { ssoSelector } from "Selectors/manageSSO";
|
||||
import { commonText, createBackspaceText } from "Texts/common";
|
||||
import { passwordInputText } from "Texts/passwordInput";
|
||||
|
||||
Cypress.Commands.add("login", (email, password) => {
|
||||
cy.visit("/");
|
||||
cy.clearAndType(loginSelectors.emailField, email);
|
||||
cy.clearAndType(loginSelectors.passwordField, password);
|
||||
cy.intercept("GET", "/api/apps?page=1&folder=&searchKey=").as("homePage");
|
||||
cy.get(loginSelectors.signInButton).click();
|
||||
cy.get(loginSelectors.homePage).should("be.visible");
|
||||
cy.wait("@homePage");
|
||||
cy.clearAndType(commonSelectors.workEmailInputField, "dev@tooljet.io");
|
||||
cy.clearAndType(commonSelectors.passwordInputField, "password");
|
||||
cy.get(commonSelectors.signInButton).click();
|
||||
cy.get(commonSelectors.homePageLogo).should("be.visible");
|
||||
cy.wait(2000)
|
||||
});
|
||||
|
||||
Cypress.Commands.add("clearAndType", (selector, text) => {
|
||||
|
|
@ -24,7 +22,7 @@ Cypress.Commands.add("forceClickOnCanvas", () => {
|
|||
});
|
||||
|
||||
Cypress.Commands.add("verifyToastMessage", (selector, message) => {
|
||||
cy.get(selector).should("be.visible").and("have.text", message);
|
||||
cy.get(selector).eq(0).should("be.visible").and("have.text", message);
|
||||
cy.get("body").then(($body) => {
|
||||
if ($body.find(commonSelectors.toastCloseButton).length > 0) {
|
||||
cy.closeToastMessage();
|
||||
|
|
@ -108,11 +106,11 @@ Cypress.Commands.add("createApp", (appName) => {
|
|||
|
||||
Cypress.Commands.add(
|
||||
"dragAndDropWidget",
|
||||
(widgetName, positionX = 190, positionY = 80) => {
|
||||
(widgetName, positionX = 190, positionY = 80, widgetName2=widgetName) => {
|
||||
const dataTransfer = new DataTransfer();
|
||||
|
||||
cy.clearAndType(commonSelectors.searchField, widgetName);
|
||||
cy.get(commonWidgetSelector.widgetBox(widgetName)).trigger(
|
||||
cy.get(commonWidgetSelector.widgetBox(widgetName2)).trigger(
|
||||
"dragstart",
|
||||
{ dataTransfer },
|
||||
{ force: true }
|
||||
|
|
@ -129,9 +127,9 @@ Cypress.Commands.add("appUILogin", () => {
|
|||
cy.visit("/");
|
||||
cy.clearAndType(commonSelectors.workEmailInputField, "dev@tooljet.io");
|
||||
cy.clearAndType(commonSelectors.passwordInputField, "password");
|
||||
cy.get(loginSelectors.signInButton).click();
|
||||
cy.get(commonSelectors.signInButton).click();
|
||||
cy.get(commonSelectors.homePageLogo).should("be.visible");
|
||||
cy.wait(2000)
|
||||
cy.wait(2000);
|
||||
cy.get("body").then(($el) => {
|
||||
if ($el.text().includes("Skip")) {
|
||||
cy.get(commonSelectors.skipInstallationModal).click();
|
||||
|
|
|
|||
45
cypress-tests/cypress/support/utils/basicComponents.js
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
import { commonWidgetSelector, commonSelectors } from "Selectors/common";
|
||||
import {
|
||||
openAccordion,
|
||||
verifyAndModifyParameter,
|
||||
openEditorSidebar,
|
||||
editAndVerifyWidgetName,
|
||||
} from "Support/utils/commonWidget";
|
||||
|
||||
export const verifyComponent = (widgetName) => {
|
||||
cy.get(commonWidgetSelector.draggableWidget(widgetName)).should("be.visible");
|
||||
};
|
||||
|
||||
export const deleteComponentAndVerify = (widgetName) => {
|
||||
cy.get(commonWidgetSelector.draggableWidget(widgetName)).click();
|
||||
cy.get(`[data-cy="${widgetName}-delete-button"]`).last().click();
|
||||
cy.notVisible(commonWidgetSelector.draggableWidget(widgetName));
|
||||
};
|
||||
|
||||
export const verifyComponentWithOutLabel=(component, defaultName, fakeName, appName, properties=[] )=>{
|
||||
cy.dragAndDropWidget(component, 50, 50);
|
||||
cy.get(`[data-cy="draggable-widget-${defaultName}"]`).click({ force: true });
|
||||
verifyComponent(defaultName);
|
||||
|
||||
cy.resizeWidget(defaultName, 850, 600);
|
||||
|
||||
openEditorSidebar(defaultName);
|
||||
editAndVerifyWidgetName(fakeName, properties);
|
||||
|
||||
cy.forceClickOnCanvas();
|
||||
cy.waitForAutoSave();
|
||||
|
||||
cy.openInCurrentTab(commonWidgetSelector.previewButton);
|
||||
verifyComponent(fakeName);
|
||||
|
||||
cy.go("back");
|
||||
deleteComponentAndVerify(fakeName);
|
||||
cy.get(commonSelectors.editorPageLogo).click();
|
||||
|
||||
cy.deleteApp(appName);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -82,8 +82,11 @@ export const addAndVerifyTooltip = (widgetSelector, message) => {
|
|||
verifyTooltip(widgetSelector, message);
|
||||
};
|
||||
|
||||
export const editAndVerifyWidgetName = (name) => {
|
||||
closeAccordions(["General", "Properties", "Layout"]);
|
||||
export const editAndVerifyWidgetName = (
|
||||
name,
|
||||
accordion = ["General", "Properties", "Layout"]
|
||||
) => {
|
||||
closeAccordions(accordion);
|
||||
cy.clearAndType(commonWidgetSelector.WidgetNameInputField, name);
|
||||
cy.get(commonWidgetSelector.buttonCloseEditorSideBar).click();
|
||||
|
||||
|
|
@ -125,25 +128,27 @@ export const verifyMultipleComponentValuesFromInspector = (
|
|||
cy.forceClickOnCanvas();
|
||||
};
|
||||
|
||||
export const selectColourFromColourPicker = (paramName, colour) => {
|
||||
export const selectColourFromColourPicker = (paramName, colour, index = 0) => {
|
||||
cy.get(commonWidgetSelector.stylePicker(paramName)).click();
|
||||
cy.get(commonWidgetSelector.colourPickerParent).within(() => {
|
||||
colour.forEach((value, i) =>
|
||||
cy
|
||||
.get(commonWidgetSelector.colourPickerInput(i + 1))
|
||||
.click()
|
||||
.clear()
|
||||
.type(value)
|
||||
.then(($input) => {
|
||||
if (!$input.val(value)) {
|
||||
cy.get(commonWidgetSelector.colourPickerInput(i + 1))
|
||||
.click()
|
||||
.clear()
|
||||
.type(value);
|
||||
}
|
||||
})
|
||||
);
|
||||
});
|
||||
cy.get(commonWidgetSelector.colourPickerParent)
|
||||
.eq(index)
|
||||
.within(() => {
|
||||
colour.forEach((value, i) =>
|
||||
cy
|
||||
.get(commonWidgetSelector.colourPickerInput(i + 1))
|
||||
.click()
|
||||
.clear()
|
||||
.type(value)
|
||||
.then(($input) => {
|
||||
if (!$input.val(value)) {
|
||||
cy.get(commonWidgetSelector.colourPickerInput(i + 1))
|
||||
.click()
|
||||
.clear()
|
||||
.type(value);
|
||||
}
|
||||
})
|
||||
);
|
||||
});
|
||||
cy.waitForAutoSave();
|
||||
};
|
||||
|
||||
|
|
@ -194,7 +199,8 @@ export const verifyComponentFromInspector = (
|
|||
export const verifyAndModifyStylePickerFx = (
|
||||
paramName,
|
||||
defaultValue,
|
||||
value
|
||||
value,
|
||||
index = 0
|
||||
) => {
|
||||
cy.get(commonWidgetSelector.parameterLabel(paramName)).should(
|
||||
"have.text",
|
||||
|
|
@ -227,9 +233,11 @@ export const verifyAndModifyStylePickerFx = (
|
|||
commonWidgetSelector.stylePickerFxInput(paramName)
|
||||
).clearAndTypeOnCodeMirror(value);
|
||||
|
||||
cy.get(commonWidgetSelector.stylePickerFxInput(paramName)).within(() => {
|
||||
cy.get(".CodeMirror-line").should("be.visible").and("have.text", value);
|
||||
});
|
||||
cy.get(commonWidgetSelector.stylePickerFxInput(paramName))
|
||||
.eq(index)
|
||||
.within(() => {
|
||||
cy.get(".CodeMirror-line").should("be.visible").and("have.text", value);
|
||||
});
|
||||
};
|
||||
|
||||
export const verifyWidgetColorCss = (widgetName, cssProperty, color) => {
|
||||
|
|
@ -266,7 +274,7 @@ export const verifyLayout = (widgetName) => {
|
|||
commonWidgetText.parameterShowOnMobile,
|
||||
commonWidgetText.codeMirrorLabelFalse
|
||||
);
|
||||
cy.get(commonWidgetSelector.changeLayoutButton).click();
|
||||
cy.get(commonWidgetSelector.changeLayoutToMobileButton).click();
|
||||
cy.get(commonWidgetSelector.draggableWidget(widgetName)).should("exist");
|
||||
};
|
||||
|
||||
|
|
@ -285,11 +293,12 @@ export const verifyStylesGeneralAccordion = (
|
|||
widgetName,
|
||||
boxShadowParameter,
|
||||
hexColor,
|
||||
boxShadowColor
|
||||
boxShadowColor,
|
||||
index = 0
|
||||
) => {
|
||||
openEditorSidebar(widgetName);
|
||||
cy.get(commonWidgetSelector.buttonStylesEditorSideBar).click();
|
||||
openAccordion(commonWidgetText.accordionGenaral, [], "1");
|
||||
openAccordion(commonWidgetText.accordionGenaral, []);
|
||||
verifyAndModifyStylePickerFx(
|
||||
commonWidgetText.parameterBoxShadow,
|
||||
commonWidgetText.boxShadowDefaultValue,
|
||||
|
|
@ -307,7 +316,11 @@ export const verifyStylesGeneralAccordion = (
|
|||
commonWidgetSelector.boxShadowDefaultParam,
|
||||
boxShadowParameter
|
||||
);
|
||||
selectColourFromColourPicker(commonWidgetText.boxShadowColor, boxShadowColor);
|
||||
selectColourFromColourPicker(
|
||||
commonWidgetText.boxShadowColor,
|
||||
boxShadowColor,
|
||||
index
|
||||
);
|
||||
|
||||
verifyBoxShadowCss(widgetName, boxShadowColor, boxShadowParameter);
|
||||
};
|
||||
|
|
@ -322,11 +335,14 @@ export const addTextWidgetToVerifyValue = (customfunction) => {
|
|||
|
||||
export const verifyTooltip = (widgetSelector, message) => {
|
||||
cy.forceClickOnCanvas();
|
||||
cy.get(widgetSelector).click();
|
||||
cy.get(widgetSelector)
|
||||
.trigger("mouseover", { timeout: 2000 })
|
||||
.trigger("mouseover")
|
||||
.then(() => {
|
||||
cy.get(commonWidgetSelector.tooltipLabel).should("have.text", message);
|
||||
cy.get(commonWidgetSelector.tooltipLabel)
|
||||
.last()
|
||||
.should("have.text", message);
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
import { commonSelectors } from "Selectors/common";
|
||||
import { dashboardSelector } from "Selectors/dashboard";
|
||||
import { dashboardText } from "Texts/dashboard";
|
||||
import { loginSelectors } from "Selectors/login";
|
||||
import { commonText } from "Texts/common";
|
||||
import {
|
||||
viewAppCardOptions,
|
||||
|
|
@ -12,9 +11,9 @@ import {
|
|||
|
||||
export const login = () => {
|
||||
cy.visit("/");
|
||||
cy.clearAndType(loginSelectors.emailField, "dev@tooljet.io");
|
||||
cy.clearAndType(loginSelectors.passwordField, "password");
|
||||
cy.get(loginSelectors.signInButton).click();
|
||||
cy.clearAndType(commonSelectors.workEmailInputField, "dev@tooljet.io");
|
||||
cy.clearAndType(commonSelectors.passwordInputField, "password");
|
||||
cy.get(commonSelectors.loginButton).click();
|
||||
};
|
||||
|
||||
export const modifyAndVerifyAppCardIcon = (appName) => {
|
||||
|
|
|
|||
14
cypress-tests/cypress/support/utils/dataSource.js
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
import { postgreSqlSelector } from "Selectors/postgreSql";
|
||||
import { postgreSqlText } from "Texts/postgreSql";
|
||||
|
||||
export const verifyCouldnotConnectWithAlert = (dangerText) => {
|
||||
cy.get(postgreSqlSelector.connectionFailedText, {
|
||||
timeout: 10000,
|
||||
}).verifyVisibleElement("have.text", postgreSqlText.couldNotConnect, {
|
||||
timeout: 5000,
|
||||
});
|
||||
cy.get(postgreSqlSelector.dangerAlertNotSupportSSL).verifyVisibleElement(
|
||||
"contain.text",
|
||||
dangerText
|
||||
);
|
||||
};
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
import { loginSelectors } from "Selectors/login";
|
||||
import { loginTexts } from "Texts/login";
|
||||
import { path } from "Texts/common";
|
||||
|
||||
export const loginPageElements = () => {
|
||||
cy.url().should("include", path.loginPath);
|
||||
cy.get(loginSelectors.logo).should("be.visible");
|
||||
cy.get(loginSelectors.cardTitle).verifyVisibleElement(
|
||||
"have.text",
|
||||
loginTexts.cardTitle
|
||||
);
|
||||
cy.get(loginSelectors.emailLabel).verifyVisibleElement(
|
||||
"have.text",
|
||||
loginTexts.emailLabel
|
||||
);
|
||||
cy.get(loginSelectors.passwordLabel)
|
||||
.should(($el) => {
|
||||
expect($el.contents().first().text().trim()).to.eq(
|
||||
loginTexts.passwordLabel
|
||||
);
|
||||
})
|
||||
.should("be.visible");
|
||||
cy.get(loginSelectors.forgotPassword).verifyVisibleElement(
|
||||
"have.text",
|
||||
loginTexts.forgotPassword
|
||||
);
|
||||
cy.get(loginSelectors.showPassword).should(
|
||||
"have.text",
|
||||
loginTexts.showPassword
|
||||
);
|
||||
cy.get(loginSelectors.signUpText).should("be.visible");
|
||||
cy.get(loginSelectors.checkBox).check();
|
||||
cy.get(loginSelectors.checkBox).uncheck();
|
||||
cy.get(loginSelectors.signUpText)
|
||||
.should(($el) => {
|
||||
expect($el.contents().first().text().trim()).to.eq(loginTexts.signUpText);
|
||||
})
|
||||
.should("be.visible");
|
||||
cy.get(loginSelectors.signUpLink).verifyVisibleElement(
|
||||
"have.text",
|
||||
loginTexts.signUpLink
|
||||
);
|
||||
};
|
||||
|
|
@ -3,7 +3,6 @@ import { ssoSelector } from "Selectors/manageSSO";
|
|||
import { ssoText } from "Texts/manageSSO";
|
||||
import * as common from "Support/utils/common";
|
||||
import { commonText } from "Texts/common";
|
||||
import { loginSelectors } from "Selectors/login";
|
||||
import { dashboardSelector } from "Selectors/dashboard";
|
||||
|
||||
export const generalSettings = () => {
|
||||
|
|
@ -286,7 +285,7 @@ export const passwordLoginVisible = () => {
|
|||
export const workspaceLogin = (workspaceName) => {
|
||||
cy.clearAndType(commonSelectors.workEmailInputField, "dev@tooljet.io");
|
||||
cy.clearAndType(commonSelectors.passwordInputField, "password");
|
||||
cy.get(loginSelectors.signInButton).click();
|
||||
cy.get(commonSelectors.loginButton).click();
|
||||
cy.get(commonSelectors.homePageLogo).should("be.visible");
|
||||
cy.get(dashboardSelector.modeToggle, { timeout: 10000 }).should("be.visible");
|
||||
cy.get(commonSelectors.workspaceName).verifyVisibleElement(
|
||||
|
|
|
|||
|
|
@ -60,15 +60,23 @@ export const fillConnectionForm = (data) => {
|
|||
cy.get(postgreSqlSelector.buttonSave).click();
|
||||
};
|
||||
|
||||
export const fillDataSourceTextField = (fieldName, placeholder, input) => {
|
||||
export const fillDataSourceTextField = (
|
||||
fieldName,
|
||||
placeholder,
|
||||
input,
|
||||
assertionType = "have",
|
||||
args
|
||||
) => {
|
||||
cy.get(`[data-cy="label-${cyParamName(fieldName)}"]`).should(
|
||||
"have.text",
|
||||
`${assertionType}.text`,
|
||||
fieldName
|
||||
);
|
||||
cy.get(`[data-cy="${cyParamName(fieldName)}-text-field"]`)
|
||||
.invoke("attr", "placeholder")
|
||||
.should("eq", placeholder.replace(/\u00a0/g, " "));
|
||||
cy.clearAndType(`[data-cy="${cyParamName(fieldName)}-text-field"]`, input);
|
||||
cy.get(`[data-cy="${cyParamName(fieldName)}-text-field"]`)
|
||||
.clear()
|
||||
.type(input, args);
|
||||
};
|
||||
|
||||
export const openQueryEditor = (dataSourceName) => {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,12 @@ DEPLOYMENT_PLATFORM=ec2
|
|||
# ToolJet Database
|
||||
ENABLE_TOOLJET_DB=false
|
||||
TOOLJET_DB=tooljet_db
|
||||
TOOLJET_DB_USER=
|
||||
TOOLJET_DB_HOST=
|
||||
TOOLJET_DB_PASS=
|
||||
PGRST_HOST=localhost:3001
|
||||
PGRST_SERVER_PORT=3001
|
||||
PGRST_JWT_SECRET=
|
||||
PGRST_DB_URI=
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -36,7 +36,6 @@ then
|
|||
fi
|
||||
|
||||
sudo npm --prefix server run db:setup:prod
|
||||
sudo npm --prefix server run db:seed:prod
|
||||
|
||||
if sudo systemctl start nest
|
||||
then
|
||||
|
|
|
|||
|
|
@ -51,6 +51,11 @@ build {
|
|||
destination = "/tmp/setup_app"
|
||||
}
|
||||
|
||||
provisioner "file" {
|
||||
source = "postgrest.service"
|
||||
destination = "/tmp/postgrest.service"
|
||||
}
|
||||
|
||||
provisioner "shell" {
|
||||
script = "setup_machine.sh"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,7 +34,13 @@ COPY ./server/ ./server/
|
|||
RUN npm install -g @nestjs/cli
|
||||
RUN npm --prefix server run build
|
||||
|
||||
FROM node:14.17.3-buster
|
||||
FROM debian:11
|
||||
|
||||
RUN apt-get update -yq \
|
||||
&& apt-get install curl gnupg zip -yq \
|
||||
&& curl -fsSL https://deb.nodesource.com/setup_14.17.3 | bash \
|
||||
&& apt-get install nodejs npm -yq \
|
||||
&& apt-get clean -y
|
||||
|
||||
ENV NODE_ENV=production
|
||||
ENV NODE_OPTIONS="--max-old-space-size=4096"
|
||||
|
|
@ -46,6 +52,7 @@ RUN apt-get update && \
|
|||
|
||||
# Install Instantclient Basic Light Oracle and Dependencies
|
||||
WORKDIR /opt/oracle
|
||||
|
||||
RUN wget https://download.oracle.com/otn_software/linux/instantclient/instantclient-basiclite-linuxx64.zip && \
|
||||
unzip instantclient-basiclite-linuxx64.zip && rm -f instantclient-basiclite-linuxx64.zip && \
|
||||
cd /opt/oracle/instantclient* && rm -f *jdbc* *occi* *mysql* *mql1* *ipc1* *jar uidrvci genezi adrci && \
|
||||
|
|
@ -76,5 +83,5 @@ RUN chgrp -R 0 /app && chmod -R g=u /app
|
|||
WORKDIR /app
|
||||
# Dependencies for scripts outside nestjs
|
||||
RUN npm install dotenv@10.0.0 joi@17.4.1
|
||||
|
||||
ENTRYPOINT ["./server/entrypoint.sh"]
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,13 @@ RUN npm --prefix server install --only=production
|
|||
COPY ./server/ ./server/
|
||||
RUN npm --prefix server run build
|
||||
|
||||
FROM node:14.17.3-buster
|
||||
FROM debian:11
|
||||
|
||||
RUN apt-get update -yq \
|
||||
&& apt-get install curl gnupg zip -yq \
|
||||
&& curl -fsSL https://deb.nodesource.com/setup_14.17.3 | bash \
|
||||
&& apt-get install nodejs npm -yq \
|
||||
&& apt-get clean -y
|
||||
|
||||
ENV NODE_ENV=production
|
||||
ENV NODE_OPTIONS="--max-old-space-size=4096"
|
||||
|
|
|
|||
|
|
@ -38,6 +38,8 @@ The App (which credentials are provided) needs to be installed in the workspace
|
|||
|
||||
1. **List members**
|
||||
2. **Send message**
|
||||
2. **List messages**
|
||||
|
||||
### List members
|
||||
|
||||
This operation will return the data of all the members in your slack workspace.
|
||||
|
|
@ -56,6 +58,8 @@ This operation will send/post the message to a specified channel or posting to d
|
|||
| :--- | :--- |
|
||||
| Channel | The channel ID or user ID to post the message to. |
|
||||
| Message | The message to post. |
|
||||
| Limit | The maximum number of messages to return. |
|
||||
| Cursor | A cursor value returned by a previous call to list messages. |
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
|
||||
|
|
@ -63,5 +67,19 @@ This operation will send/post the message to a specified channel or posting to d
|
|||
|
||||
</div>
|
||||
|
||||
### List messages
|
||||
|
||||
This operation will get the messages from a specified channel.
|
||||
|
||||
| Property | Description |
|
||||
| :--- |:----------------------------------------|
|
||||
| Channel | The channel ID to get the messages from |
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
|
||||

|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
BIN
docs/static/img/datasource-reference/slack/listmessages.png
vendored
Normal file
|
After Width: | Height: | Size: 97 KiB |
BIN
frontend/assets/py-v0.21.3/pyodide.asm.wasm → docs/static/img/how-to/import-python/console.gif
vendored
Executable file → Normal file
|
Before Width: | Height: | Size: 8.4 MiB After Width: | Height: | Size: 8.5 MiB |
BIN
docs/static/img/how-to/import-python/csvparse.png
vendored
Normal file
|
After Width: | Height: | Size: 174 KiB |
BIN
docs/static/img/how-to/import-python/event.png
vendored
Normal file
|
After Width: | Height: | Size: 131 KiB |
BIN
docs/static/img/how-to/import-python/installing.png
vendored
Normal file
|
After Width: | Height: | Size: 122 KiB |
BIN
docs/static/img/how-to/import-python/random.gif
vendored
Normal file
|
After Width: | Height: | Size: 2.2 MiB |
BIN
docs/static/img/how-to/import-python/runpy.png
vendored
Normal file
|
After Width: | Height: | Size: 356 KiB |
|
|
@ -26,6 +26,6 @@ You will be redirected to the visual app editor once the app has been created. C
|
|||
|
||||
The main components of an app:
|
||||
|
||||
- **[Widgets](https://docs.tooljet.com/docs/tutorial/adding-widget)** - UI components such as tables, buttons, dropdowns.
|
||||
- **[Widgets](https://docs.tooljet.com/docs/tutorial/adding-widget)** - UI components such as tables, buttons, and dropdowns etc.
|
||||
- **[Data sources](https://docs.tooljet.com/docs/tutorial/adding-a-datasource)** - ToolJet can connect to databases, APIs and external services to fetch and modify data.
|
||||
- **[Queries](https://docs.tooljet.com/docs/tutorial/building-queries)** - Queries are used to access the connected data sources.
|
||||
- **[Queries](https://docs.tooljet.com/docs/tutorial/building-queries)** - Queries are used to access the connected data sources.
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ ToolJet comes with flexible components to group other components together, such
|
|||
|
||||
### Hide or Disable Components
|
||||
|
||||
Hide or Disable a component by settting it's **Visibility** or **Disabled** property to `true`. Click on the component handle to open **config inspector** on right side. These values can also evaluate to true based on a truthy value. For example, you can use the property of one component to toggle the Visibility property of another component dynamically, you just need to write a conditional statement.
|
||||
Hide or Disable a component by setting its **Visibility** or **Disabled** property to `true`. Click on the component handle to open **config inspector** on right side. These values can also evaluate to true based on a truthy value. For example, you can use the property of one component to toggle the Visibility property of another component dynamically, you just need to write a conditional statement.
|
||||
|
||||
For example: We want to disable a button when a checkbox is checked so we can simple use `{{components.checkbox1.value}}` in **Disable** property of the button. `{{components.checkbox1.value}}` evaluates to `true` when the checkbox is checked, and false when unchecked.
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ ToolJet's App Builder allows you to build applications. ToolJet's app builder ha
|
|||
|
||||
- **[Toolbar](/docs/app-builder/toolbar)**: configure app settings
|
||||
- **[Canvas](/docs/app-builder/canvas)**: Arrange the components to build the interface of app
|
||||
- **[Left-sidebar](/docs/app-builder/left-sidebar)**: Add **[pages](/docs/tutorial/pages)**, **[datasources](/docs/data-sources/overview)**, **[inspect](/docs/how-to/use-inspector)** the componenets, queries or variables, and **[debug](#debugger)** the errors.
|
||||
- **[Left-sidebar](/docs/app-builder/left-sidebar)**: Add **[pages](/docs/tutorial/pages)**, **[datasources](/docs/data-sources/overview)**, **[inspect](/docs/how-to/use-inspector)** the components, queries or variables, and **[debug](#debugger)** the errors.
|
||||
- **[Components library](/docs/app-builder/components-library)**(right sidebar): Drag any component or modify the property or styling
|
||||
- **[Query Panel](/docs/app-builder/query-panel)**: Create, edit or manage the queries
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ Query Manager will list all the queries that has been created in the application
|
|||
|
||||
### Search
|
||||
|
||||
On the top of the query manager is search box that can be used to search for a specif query.
|
||||
On the top of the query manager is search box that can be used to search for a specific query.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ Comment anywhere on the canvas and collaborate with other users in the workspace
|
|||
Share your applications with a unique URL generated automatically or edit the URL slug to personalize it.
|
||||
|
||||
- When **Make the application public** is off and URL is shared then the users will have to login to ToolJet to use the application. Toggle on the option then anyone on the internet will be able to access the application without logging in to ToolJet.
|
||||
- ToolJet generates the **Embedded link** which can be used to embedd application on the webpages.
|
||||
- ToolJet generates the **Embedded link** which can be used to embed application on the webpages.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
|
||||
|
|
|
|||
|
|
@ -101,18 +101,7 @@ Please find more information [here](https://docs.docker.com/desktop/windows/wsl/
|
|||
```bash
|
||||
docker-compose up
|
||||
```
|
||||
|
||||
6. ToolJet server is built using NestJS and the data such as application definitions are persisted on a postgres database. You can run the below command to seed the database.
|
||||
|
||||
```bash
|
||||
docker-compose exec server npm run db:seed
|
||||
```
|
||||
|
||||
7. ToolJet should now be served locally at `http://localhost:8082`. You can login using the default user created.
|
||||
```
|
||||
email: dev@tooljet.io
|
||||
password: password
|
||||
```
|
||||
ToolJet should now be served locally at `http://localhost:8082`.
|
||||
|
||||
8. To shut down the containers,
|
||||
```bash
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ You can write custom Python code to interact with components and queries. To do
|
|||
#### Example: Using Python code to trigger component specific actions
|
||||
|
||||
- Let's drag a **button** and a **text** widget onto the canvas. We will set a text on the text component and trigger button click event from the Python query.
|
||||
- Click on the `+` on the query panel to create a query and select **Run JavaScript code** from the available datasources
|
||||
- Click on the `+` on the query panel to create a query and select **Run Python code** from the available datasources
|
||||
- Let's write the code in **Python Editor** and save the query:
|
||||
|
||||
```python
|
||||
|
|
@ -52,4 +52,4 @@ You can also write custom Python code to get the data from **External APIs** and
|
|||
|
||||
:::info
|
||||
Issues with writing custom Python code? Ask in our [Slack community](https://www.tooljet.com/slack).
|
||||
:::
|
||||
:::
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ When you're building an internal tool, there are a lot of tools and frameworks a
|
|||
|
||||
- **Open-Source**: ToolJet is Open-Source, you can go through the ToolJet codebase on **[GitHub](https://github.com/ToolJet/ToolJet)** or you can **deploy ToolJet on your infrastructure**.
|
||||
- **Full-stack platform**: ToolJet has a **[built-in database](/docs/tooljet-database)**, **[External datasources](/docs/data-sources/airtable)**, and a frontend builder so you can build a full-stack app right inside it. ToolJet comes with Custom Component for importing your own **react components** and the ability to write custom **JavaScript** and **Python** code.
|
||||
- **Extensible**: Didn't find the **component** or **datasource** that fit your application's requirements? You can always build your own **component** and **datasource** using our **plugin developement kit**.
|
||||
- **Extensible**: Didn't find the **component** or **datasource** that fit your application's requirements? You can always build your own **component** and **datasource** using our **plugin development kit**.
|
||||
- **Powerful Apps**: With ToolJet, developers can quickly build powerful custom internal tools for their Support, Operations and Sales teams. Build CRUD apps, Dashboards, Admin Panels, CRMs and much more.
|
||||
|
||||
-->
|
||||
|
|
@ -56,7 +56,7 @@ When you're building an internal tool, there are a lot of tools and frameworks a
|
|||
There are a few different ways to set up ToolJet depending on how you intend to use it:
|
||||
|
||||
- **[ToolJet Cloud](https://www.tooljet.com)**: hosted solution, just sign-up for free and start building apps in seconds.
|
||||
- **[Deploy on premise](/docs/setup/)**: recommended method for production or customized use cases. You'll find Server setup guides for popular platforms (AWS, GCP, Kubernetes etc) and one-click deployement guides (Heroku, DigitalOcean etc).
|
||||
- **[Deploy on premise](/docs/setup/)**: recommended method for production or customized use cases. You'll find Server setup guides for popular platforms (AWS, GCP, Kubernetes etc) and one-click deployment guides (Heroku, DigitalOcean etc).
|
||||
- **[Try ToolJet on local machine](/docs/setup/try-tooljet/)**: the fastest way to try out ToolJet on your computer using docker.
|
||||
|
||||
:::info
|
||||
|
|
@ -159,7 +159,7 @@ ToolJet application's User interface is constructed using Components like Tables
|
|||
ToolJet can connect to several databases, APIs and external services to fetch and modify data. Check **Datasource Catalog** to learn more.
|
||||
:::
|
||||
|
||||
2. Choose a **Table** from the dropdown, Select the **List rows** option from the **Operation** dropdown, You can leave other query parameters. Scroll down and enable **Run this query on application load** - this will trigger the query when the app is laoded.
|
||||
2. Choose a **Table** from the dropdown, Select the **List rows** option from the **Operation** dropdown, You can leave other query parameters. Scroll down and enable **Run this query on application load** - this will trigger the query when the app is loaded.
|
||||
|
||||
3. Click on **Create** to create the query and then click **Run** to trigger the query and get response. You can also check the query response by clicking **Preview** button without firing the query.
|
||||
<div style={{textAlign: 'center'}}>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,98 @@
|
|||
---
|
||||
id: import-external-libraries-using-runpy
|
||||
title: Import external libraries using RunPy
|
||||
---
|
||||
|
||||
ToolJet allows you to utilize python packages in your app by importing them using the [RunPy query](/docs/data-sources/run-py).
|
||||
In this how-to guide, we will import a few packages and use it in the application.
|
||||
|
||||
:::caution Unsupported modules
|
||||
The modules that are not currently supported in Pyodide are those that have C or C++ extensions that rely on system libraries. These modules cannot be used in Pyodide because it runs in a web browser, which does not have access to the underlying system libraries that the C or C++ extensions rely on. Additionally, Pyodide uses a version of Python that has been compiled to WebAssembly, which does not support the same system calls as a regular version of Python. Therefore, any module that requires access to system libraries or system calls will not work in Pyodide.
|
||||
:::
|
||||
|
||||
- Create a new application and then create a new RunPy query from the query panel.
|
||||
<div style={{textAlign: 'center'}}>
|
||||
|
||||
<img className="screenshot-full" src="/img/how-to/import-python/runpy.png" alt="Import external libraries using RunPy" />
|
||||
|
||||
</div>
|
||||
|
||||
- Let's write some code for importing packages. We will first import the micropip which is a package installer for Python and then we will install the `Pandas` and `NumPy` using micropip. **Run** the query to install the packages.
|
||||
```python
|
||||
import micropip
|
||||
await micropip.install('pandas')
|
||||
await micropip.install('numpy')
|
||||
```
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
|
||||
<img className="screenshot-full" src="/img/how-to/import-python/installing.png" alt="Import external libraries using RunPy"/>
|
||||
|
||||
</div>
|
||||
|
||||
:::tip
|
||||
Enable the **Run this query on application load?** option to make the packages available throughout the application.
|
||||
:::
|
||||
|
||||
## Examples
|
||||
|
||||
### Array of random numbers of using NumPy
|
||||
|
||||
- Let's create a **RunPy** query that will use **random** module from the **NumPy** package and the query will generate array of random numbers.
|
||||
```python
|
||||
from numpy import random
|
||||
|
||||
x = random.binomial(n=10, p=0.5, size=10)
|
||||
|
||||
print(x)
|
||||
```
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
|
||||
<img className="screenshot-full" src="/img/how-to/import-python/random.gif" alt="Import external libraries using RunPy"/>
|
||||
|
||||
</div>
|
||||
|
||||
:::info
|
||||
You can check the output on the browser's console.
|
||||
:::
|
||||
|
||||
### Parse CSV data using
|
||||
|
||||
- Let's create a RunPy query that will parse the data from the csv file. In this query we will use `StringIO`, `csv`, and `Pandas` module.
|
||||
```python
|
||||
from io import StringIO
|
||||
import csv
|
||||
import pandas as pd
|
||||
|
||||
scsv = components.filepicker1.file[0].content
|
||||
|
||||
f = StringIO(scsv)
|
||||
reader = csv.reader(f, delimiter=',')
|
||||
|
||||
df = pd.DataFrame(reader)
|
||||
|
||||
print(df.info())
|
||||
print(df)
|
||||
```
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
|
||||
<img className="screenshot-full" src="/img/how-to/import-python/csvparse.png" alt="Import external libraries using RunPy"/>
|
||||
|
||||
</div>
|
||||
|
||||
- Add a file picker component on the canvas and set a event handler for **On file loaded** event to **Run Query** that we created for parsing the data.
|
||||
<div style={{textAlign: 'center'}}>
|
||||
|
||||
<img className="screenshot-full" src="/img/how-to/import-python/event.png" alt="Import external libraries using RunPy"/>
|
||||
|
||||
</div>
|
||||
|
||||
- Finally, let's load a csv file on the file picker and check the output by the RunPy query on the browser console.
|
||||
<div style={{textAlign: 'center'}}>
|
||||
|
||||
<img className="screenshot-full" src="/img/how-to/import-python/console.gif" alt="Import external libraries using RunPy"/>
|
||||
|
||||
</div>
|
||||
|
||||
|
|
@ -84,7 +84,7 @@ In this how-to guide, we will be building a simple application that will leverag
|
|||
- Now, this application can be used to load the data from the Google Sheet and the form can be used to append more records to the sheet.
|
||||
|
||||
:::tip
|
||||
- Make sure to enable **Run query on page load?** option of the **read** query to populate the table everytime the app is laoded
|
||||
- You can also add a event handler on the **append** query to run the **read** query when **append** is succesfull, this will update the table data when the append is done
|
||||
- Make sure to enable **Run query on page load?** option of the **read** query to populate the table everytime the app is loaded
|
||||
- You can also add a event handler on the **append** query to run the **read** query when **append** is successful, this will update the table data when the append is done
|
||||
- Learn more about the connecting Google sheet datasource and the CRUD **operations** available [here](/docs/data-sources/google.sheets).
|
||||
:::
|
||||
|
|
|
|||
|
|
@ -125,7 +125,7 @@ If you intend to use this feature, you'd have to set up and deploy PostgREST ser
|
|||
<img className="screenshot-full" src="/img/cloud-run/port-and-capacity-postgrest.png" alt="port-and-capacity-postgrest" />
|
||||
</div>
|
||||
|
||||
5. Under environmental variable please add correponding Tooljet database env variables. You can also refer [env variable](/docs/setup/env-vars#tooljet-database).
|
||||
5. Under environmental variable please add corresponding Tooljet database env variables. You can also refer [env variable](/docs/setup/env-vars#tooljet-database).
|
||||
|
||||
6. Please go to connection tab. Under Cloud SQL instance please select the PostgreSQL database which you have set-up for Tooljet application or the separate PostgreSQL database created respective to Tooljet Database from the drop-down option.
|
||||
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ If this parameter is not specified then PostgREST refuses authentication request
|
|||
| PGRST_LOG_LEVEL | `info` |
|
||||
|
||||
:::info
|
||||
Please make sure that DB_URI is given in the format `postgrest://[USERNAME]:[PASSWORD]@[HOST]:[PORT]/[DATABASE]`
|
||||
Please make sure that DB_URI is given in the format `postgres://[USERNAME]:[PASSWORD]@[HOST]:[PORT]/[DATABASE]`
|
||||
:::
|
||||
|
||||
#### Additional ToolJet server configuration
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ You can open the **Pages Panel** by clicking on the **Pages** icon on the left s
|
|||
|
||||
### Add Page
|
||||
|
||||
On the header of the Pages Manger, the **+** button that allows you to add more pages to your application
|
||||
On the header of the Pages Manager, the **+** button that allows you to add more pages to your application
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
|
||||
|
|
@ -45,7 +45,7 @@ On clicking the **+** button, a new page will be added, enter the name for the p
|
|||
|
||||
</div>
|
||||
|
||||
### Setttings
|
||||
### Settings
|
||||
|
||||
From **Settings**, you can hide the **page navigation sidebar** in viewer mode, by enabling the **Disable Menu** option.
|
||||
<div style={{textAlign: 'center'}}>
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ Components can be dragged and dropped from the Component Library(from the right
|
|||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
|
||||
<img className="screenshot-full" src="/img/widgets/overview/dragv2.gif" alt="Componenets: Overview" />
|
||||
<img className="screenshot-full" src="/img/widgets/overview/dragv2.gif" alt="Components: Overview" />
|
||||
|
||||
</div>
|
||||
|
||||
|
|
@ -23,7 +23,7 @@ For moving the **multiple components** at once, simply **shift+click**, to selec
|
|||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
|
||||
<img className="screenshot-full" src="/img/widgets/overview/selectv2.gif" alt="Componenets: Overview" />
|
||||
<img className="screenshot-full" src="/img/widgets/overview/selectv2.gif" alt="Components: Overview" />
|
||||
|
||||
</div>
|
||||
|
||||
|
|
@ -31,7 +31,7 @@ You can also create a selection triangle and move multiple components together b
|
|||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
|
||||
<img className="screenshot-full" src="/img/widgets/overview/dragselv2.gif" alt="Componenets: Overview" />
|
||||
<img className="screenshot-full" src="/img/widgets/overview/dragselv2.gif" alt="Components: Overview" />
|
||||
|
||||
</div>
|
||||
|
||||
|
|
@ -45,7 +45,7 @@ Each Component can be modified and styled from the Properties Panel such as the
|
|||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
|
||||
<img className="screenshot-full" src="/img/widgets/overview/props.png" alt="Componenets: Overview" />
|
||||
<img className="screenshot-full" src="/img/widgets/overview/props.png" alt="Components: Overview" />
|
||||
|
||||
</div>
|
||||
|
||||
|
|
@ -59,7 +59,7 @@ Check all the available Actions **[here](/docs/category/actions-reference)**.
|
|||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
|
||||
<img className="screenshot-full" src="/img/widgets/overview/events.png" alt="Componenets: Overview" />
|
||||
<img className="screenshot-full" src="/img/widgets/overview/events.png" alt="Components: Overview" />
|
||||
|
||||
</div>
|
||||
|
||||
|
|
@ -67,7 +67,7 @@ Check all the available Actions **[here](/docs/category/actions-reference)**.
|
|||
|
||||
Bindings allow you to get dynamic data into the components. Anything inside of **`{{}}`** is evaluated as a JavaScript expression in ToolJet.
|
||||
|
||||
Any arbitary JavaScript code can be written inside **`{{}}`**:
|
||||
Any arbitrary JavaScript code can be written inside **`{{}}`**:
|
||||
```js
|
||||
{{(function () {
|
||||
<your_javascript_code_here>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
id: star
|
||||
id: star-rating
|
||||
title: Star rating
|
||||
---
|
||||
# Star rating
|
||||
|
|
@ -82,4 +82,4 @@ Toggle on or off to control the visibility of the widget. You can programmatical
|
|||
|
||||
### Disable
|
||||
|
||||
This is `off` by default, toggle `on` the switch to lock the widget and make it non-functional. You can also programmatically set the value by clicking on the `Fx` button next to it. If set to `{{true}}`, the widget will be locked and becomes non-functional. By default, its value is set to `{{false}}`.
|
||||
This is `off` by default, toggle `on` the switch to lock the widget and make it non-functional. You can also programmatically set the value by clicking on the `Fx` button next to it. If set to `{{true}}`, the widget will be locked and becomes non-functional. By default, its value is set to `{{false}}`.
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@
|
|||
"widgets/range-slider",
|
||||
"widgets/rich-text-editor",
|
||||
"widgets/spinner",
|
||||
"widgets/star",
|
||||
"widgets/star-rating",
|
||||
"widgets/statistics",
|
||||
"widgets/steps",
|
||||
"widgets/svg-image",
|
||||
|
|
@ -283,6 +283,7 @@
|
|||
"how-to/access-cellvalue-rowdata",
|
||||
"how-to/bulk-update-multiple-rows",
|
||||
"how-to/access-currentuser",
|
||||
"how-to/import-external-libraries-using-runpy",
|
||||
"how-to/run-actions-from-runjs",
|
||||
"how-to/run-query-at-specified-intervals",
|
||||
"how-to/access-users-location",
|
||||
|
|
|
|||
|
|
@ -77,6 +77,7 @@ export const CreateVersion = ({
|
|||
type="text"
|
||||
onChange={(e) => setVersionName(e.target.value)}
|
||||
className="form-control"
|
||||
data-cy="version-name-input-field"
|
||||
placeholder={t('editor.appVersionManager.enterVersionName', 'Enter version name')}
|
||||
disabled={isCreatingVersion}
|
||||
value={versionName}
|
||||
|
|
@ -88,8 +89,10 @@ export const CreateVersion = ({
|
|||
</div>
|
||||
|
||||
<div className="mb-4 pb-2">
|
||||
<label className="form-label">{t('editor.appVersionManager.createVersionFrom', 'Create version from')}</label>
|
||||
<div className="ts-control">
|
||||
<label className="form-label" data-cy="create-version-from-label">
|
||||
{t('editor.appVersionManager.createVersionFrom', 'Create version from')}
|
||||
</label>
|
||||
<div className="ts-control" data-cy="create-version-from-input-field">
|
||||
<Select
|
||||
options={options}
|
||||
defaultValue={options[options.length - 1]}
|
||||
|
|
@ -131,6 +134,7 @@ export const CreateVersion = ({
|
|||
<div className="col d-flex justify-content-end">
|
||||
<button
|
||||
className="btn mx-2"
|
||||
data-cy="cancel-button"
|
||||
onClick={() => {
|
||||
closeCreateVersionModalPrompt();
|
||||
setShowCreateAppVersion(false);
|
||||
|
|
@ -139,7 +143,11 @@ export const CreateVersion = ({
|
|||
>
|
||||
{t('globals.cancel', 'Cancel')}
|
||||
</button>
|
||||
<button className={`btn btn-primary ${isCreatingVersion ? 'btn-loading' : ''}`} type="submit">
|
||||
<button
|
||||
className={`btn btn-primary ${isCreatingVersion ? 'btn-loading' : ''}`}
|
||||
data-cy="create-new-version-button"
|
||||
type="submit"
|
||||
>
|
||||
<svg
|
||||
className="icon"
|
||||
width="21"
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ const Menu = (props) => {
|
|||
|
||||
const SingleValue = ({ selectProps, data }) => {
|
||||
return (
|
||||
<div className="d-inline-flex align-items-center">
|
||||
<div className="d-inline-flex align-items-center" data-cy="app-version-label">
|
||||
<svg className="me-2" width="35" height="21" viewBox="0 0 35 21" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
|
|
@ -82,7 +82,10 @@ const SingleValue = ({ selectProps, data }) => {
|
|||
fill="#E03177"
|
||||
/>
|
||||
</svg>
|
||||
<div className={cx('app-version-name', { 'color-light-green': selectProps.value.isReleasedVersion })}>
|
||||
<div
|
||||
className={cx('app-version-name', { 'color-light-green': selectProps.value.isReleasedVersion })}
|
||||
data-cy={`${selectProps.value?.appVersionName}-current-version-text`}
|
||||
>
|
||||
{selectProps.value?.appVersionName}
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -112,6 +115,7 @@ export const CustomSelect = ({ ...props }) => {
|
|||
<Select
|
||||
width={'100%'}
|
||||
classNamePrefix="custom-version-selector"
|
||||
data-cy={`test-version-selector`}
|
||||
hasSearch={false}
|
||||
components={{ Menu, SingleValue }}
|
||||
setShowEditAppVersion={setShowEditAppVersion}
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ export const AppVersionsManager = function ({
|
|||
};
|
||||
|
||||
return (
|
||||
<div className="app-versions-selector">
|
||||
<div className="app-versions-selector" data-cy="app-version-selector">
|
||||
<CustomSelect
|
||||
isLoading={appVersionStatus === 'loading'}
|
||||
options={options}
|
||||
|
|
|
|||
|
|
@ -331,6 +331,7 @@ export const Box = function Box({
|
|||
mode={mode}
|
||||
resetComponent={() => setResetStatus(true)}
|
||||
childComponents={childComponents}
|
||||
dataCy={`draggable-widget-${String(component.name).toLowerCase()}`}
|
||||
></ComponentToRender>
|
||||
) : (
|
||||
<></>
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ const Content = ({ notifications, loading, darkMode }) => {
|
|||
>
|
||||
<div className="d-flex justify-content-between">
|
||||
<span className="comment-notification-user">
|
||||
{`${comment.user?.firstName} ${comment.user?.lastName}`}{' '}
|
||||
{`${comment.user?.firstName} ${comment.user?.lastName ?? ''}`}{' '}
|
||||
</span>
|
||||
<div className={`comment-notification-count ms-auto ${darkMode && 'text-light'}`}>
|
||||
{moment(comment.createdAt).fromNow()}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import cx from 'classnames';
|
|||
var tinycolor = require('tinycolor2');
|
||||
|
||||
export const Button = function Button(props) {
|
||||
const { height, properties, styles, fireEvent, registerAction, component, id } = props;
|
||||
const { height, properties, styles, fireEvent, registerAction, component, id, dataCy } = props;
|
||||
const { backgroundColor, textColor, borderRadius, loaderColor, disabledState, borderColor } = styles;
|
||||
|
||||
const [label, setLabel] = useState(properties.text);
|
||||
|
|
@ -101,7 +101,7 @@ export const Button = function Button(props) {
|
|||
onMouseOver={() => {
|
||||
fireEvent('onHover');
|
||||
}}
|
||||
data-cy={`draggable-widget-${String(component.name).toLowerCase()}`}
|
||||
data-cy={dataCy}
|
||||
type="default"
|
||||
>
|
||||
{label}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,14 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
|
||||
export const ButtonGroup = function Button({ height, properties, styles, fireEvent, setExposedVariable, darkMode }) {
|
||||
export const ButtonGroup = function Button({
|
||||
height,
|
||||
properties,
|
||||
styles,
|
||||
fireEvent,
|
||||
setExposedVariable,
|
||||
darkMode,
|
||||
dataCy,
|
||||
}) {
|
||||
const { values, labels, label, defaultSelected, multiSelection } = properties;
|
||||
const {
|
||||
backgroundColor,
|
||||
|
|
@ -60,7 +68,7 @@ export const ButtonGroup = function Button({ height, properties, styles, fireEve
|
|||
}
|
||||
};
|
||||
return (
|
||||
<div className="widget-buttongroup" style={{ height }}>
|
||||
<div className="widget-buttongroup" style={{ height }} data-cy={dataCy}>
|
||||
{label && <p className={`widget-buttongroup-label ${darkMode && 'text-light'}`}>{label}</p>}
|
||||
<div>
|
||||
{data?.map((item, index) => (
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ export const Calendar = function ({
|
|||
removeComponent,
|
||||
setExposedVariable,
|
||||
exposedVariables,
|
||||
dataCy,
|
||||
}) {
|
||||
const style = { height };
|
||||
const resourcesParam = properties.resources?.length === 0 ? {} : { resources: properties.resources };
|
||||
|
|
@ -124,7 +125,7 @@ export const Calendar = function ({
|
|||
}
|
||||
|
||||
return (
|
||||
<div id={id} style={{ display: styles.visibility ? 'block' : 'none' }}>
|
||||
<div id={id} style={{ display: styles.visibility ? 'block' : 'none' }} data-cy={dataCy}>
|
||||
<ReactCalendar
|
||||
className={`calendar-widget
|
||||
${darkMode ? 'dark-mode' : ''}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import createPlotlyComponent from 'react-plotly.js/factory';
|
|||
import { isJson } from '@/_helpers/utils';
|
||||
const Plot = createPlotlyComponent(Plotly);
|
||||
|
||||
export const Chart = function Chart({ width, height, darkMode, properties, styles }) {
|
||||
export const Chart = function Chart({ width, height, darkMode, properties, styles, dataCy }) {
|
||||
const [loadingState, setLoadingState] = useState(false);
|
||||
|
||||
const { padding, visibility, disabledState } = styles;
|
||||
|
|
@ -124,7 +124,7 @@ export const Chart = function Chart({ width, height, darkMode, properties, style
|
|||
);
|
||||
|
||||
return (
|
||||
<div data-disabled={disabledState} style={computedStyles}>
|
||||
<div data-disabled={disabledState} style={computedStyles} data-cy={dataCy}>
|
||||
{loadingState === true ? (
|
||||
<div style={{ width }} className="p-2 loader-main-container">
|
||||
<center>
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ export const Checkbox = function Checkbox({
|
|||
setExposedVariable,
|
||||
registerAction,
|
||||
darkMode,
|
||||
dataCy,
|
||||
}) {
|
||||
const defaultValueFromProperties = properties.defaultValue ?? false;
|
||||
const [defaultValue, setDefaultvalue] = React.useState(defaultValueFromProperties);
|
||||
|
|
@ -43,7 +44,12 @@ export const Checkbox = function Checkbox({
|
|||
);
|
||||
|
||||
return (
|
||||
<div data-disabled={disabledState} className="row py-1" style={{ height, display: visibility ? '' : 'none' }}>
|
||||
<div
|
||||
data-disabled={disabledState}
|
||||
className="row py-1"
|
||||
style={{ height, display: visibility ? '' : 'none' }}
|
||||
data-cy={dataCy}
|
||||
>
|
||||
<div className="col px-1 py-0 mt-0">
|
||||
<label className="mx-1 form-check form-check-inline">
|
||||
<input
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import React from 'react';
|
|||
import { CircularProgressbar } from 'react-circular-progressbar';
|
||||
import 'react-circular-progressbar/dist/styles.css';
|
||||
|
||||
export const CircularProgressBar = function CircularProgressBar({ height, properties, styles }) {
|
||||
export const CircularProgressBar = function CircularProgressBar({ height, properties, styles, dataCy }) {
|
||||
const { text, progress } = properties;
|
||||
const { visibility, color, textColor, textSize, strokeWidth, counterClockwise, circleRatio } = styles;
|
||||
|
||||
|
|
@ -11,7 +11,7 @@ export const CircularProgressBar = function CircularProgressBar({ height, proper
|
|||
};
|
||||
|
||||
return (
|
||||
<div style={computedStyles}>
|
||||
<div style={computedStyles} data-cy={dataCy}>
|
||||
<CircularProgressbar
|
||||
value={progress}
|
||||
text={text}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import 'codemirror/theme/duotone-light.css';
|
|||
import 'codemirror/theme/monokai.css';
|
||||
import { onBeforeChange, handleChange } from '../CodeBuilder/utils';
|
||||
|
||||
export const CodeEditor = ({ height, darkMode, properties, styles, exposedVariables, setExposedVariable }) => {
|
||||
export const CodeEditor = ({ height, darkMode, properties, styles, exposedVariables, setExposedVariable, dataCy }) => {
|
||||
const { enableLineNumber, mode, placeholder } = properties;
|
||||
const { visibility, disabledState } = styles;
|
||||
|
||||
|
|
@ -39,7 +39,7 @@ export const CodeEditor = ({ height, darkMode, properties, styles, exposedVariab
|
|||
}
|
||||
|
||||
return (
|
||||
<div data-disabled={disabledState} style={editorStyles}>
|
||||
<div data-disabled={disabledState} style={editorStyles} data-cy={dataCy}>
|
||||
<div
|
||||
className={`code-hinter codehinter-default-input code-editor-widget`}
|
||||
style={{
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ export const ColorPicker = function ({
|
|||
height,
|
||||
registerAction,
|
||||
fireEvent,
|
||||
dataCy,
|
||||
}) {
|
||||
const { visibility } = styles;
|
||||
const defaultColor = properties.defaultColor;
|
||||
|
|
@ -114,7 +115,7 @@ export const ColorPicker = function ({
|
|||
: { display: 'none' };
|
||||
|
||||
return (
|
||||
<div style={baseStyle} className="form-control">
|
||||
<div style={baseStyle} className="form-control" data-cy={dataCy}>
|
||||
<div className="d-flex h-100 justify-content-between align-items-center" onClick={() => setShowColorPicker(true)}>
|
||||
<span>{color}</span>
|
||||
{!(color === `Invalid Color`) && <div style={backgroundColorDivStyle}></div>}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ export const Container = function Container({
|
|||
removeComponent,
|
||||
styles,
|
||||
darkMode,
|
||||
dataCy,
|
||||
}) {
|
||||
const { visibility, disabledState, borderRadius, borderColor } = styles;
|
||||
const backgroundColor =
|
||||
|
|
@ -30,6 +31,7 @@ export const Container = function Container({
|
|||
data-disabled={disabledState}
|
||||
className="jet-container"
|
||||
id={id}
|
||||
data-cy={dataCy}
|
||||
ref={parentRef}
|
||||
style={computedStyles}
|
||||
onClick={(e) => {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,8 @@ import { isEqual } from 'lodash';
|
|||
import iframeContent from './iframe.html';
|
||||
|
||||
export const CustomComponent = (props) => {
|
||||
const { height, properties, styles, id, setExposedVariable, exposedVariables, fireEvent, dataQueries } = props;
|
||||
const { height, properties, styles, id, setExposedVariable, exposedVariables, fireEvent, dataQueries, dataCy } =
|
||||
props;
|
||||
const { visibility } = styles;
|
||||
const { code, data } = properties;
|
||||
const [customProps, setCustomProps] = useState(data);
|
||||
|
|
@ -93,7 +94,7 @@ export const CustomComponent = (props) => {
|
|||
};
|
||||
|
||||
return (
|
||||
<div className="card" style={{ display: visibility ? '' : 'none', height }}>
|
||||
<div className="card" style={{ display: visibility ? '' : 'none', height }} data-cy={dataCy}>
|
||||
<iframe
|
||||
srcDoc={iframeContent}
|
||||
style={{ width: '100%', height: '100%', border: 'none' }}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ export const Datepicker = function Datepicker({
|
|||
id,
|
||||
darkMode,
|
||||
fireEvent,
|
||||
dataCy,
|
||||
}) {
|
||||
const { enableTime, enableDate, defaultValue, disabledDates } = properties;
|
||||
const format = typeof properties.format === 'string' ? properties.format : '';
|
||||
|
|
@ -80,7 +81,7 @@ export const Datepicker = function Datepicker({
|
|||
<div
|
||||
data-disabled={disabledState}
|
||||
className={`datepicker-widget ${darkMode && 'theme-dark'}`}
|
||||
data-cy={`draggable-widget-${String(component.name).toLowerCase()}`}
|
||||
data-cy={dataCy}
|
||||
style={{
|
||||
height,
|
||||
display: visibility ? '' : 'none',
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ export const DaterangePicker = function DaterangePicker({
|
|||
width,
|
||||
darkMode,
|
||||
fireEvent,
|
||||
dataCy,
|
||||
}) {
|
||||
const { borderRadius, visibility, disabledState } = styles;
|
||||
const { defaultStartDate, defaultEndDate } = properties;
|
||||
|
|
@ -66,6 +67,7 @@ export const DaterangePicker = function DaterangePicker({
|
|||
<div
|
||||
className={`daterange-picker-widget ${darkMode && 'theme-dark'} p-0`}
|
||||
style={{ height, display: visibility ? '' : 'none' }}
|
||||
data-cy={dataCy}
|
||||
>
|
||||
<DateRangePicker
|
||||
disabled={disabledState}
|
||||
|
|
|
|||