mirror of
https://github.com/ToolJet/ToolJet
synced 2026-05-23 17:08:34 +00:00
Appbuilder sprint 5 merge main (#11573)
* statement timeout for postgresql mssql mysql can now be configured from env * Enhance: Add clear all, cancel & apply functionality to TJDB filter-popup (#2344) * Update filter inputs * Update filter body * Style fixes * Handle invalid filters * Fix bugs * Feature: Add list all sheets and create new spreadsheet operation to GoogleSheets (#2370) * Add create spreadsheet functionality * Add list all sheets functionality * Updated delete and batch-update methods * Change interface to type * Enhance: Add read documentation link with data source drop down in query builder (#2162) * Add read-documentation link * Change copywriting for datasources name * Update new component for link * Increase input width Update redshift link * Fix the datasource name issue * Enhance: Improve error handling in Google-Sheets run query (#2286) * Add error details * Display error for incorrect JSON * Throw error for empty spreadsheetid and operator * Enhance: Error handling for PgSql, MySql and MsSql (#2389) * Enhance error handling for pgsql * Enhance error handling for mysql * Remove console logs * Enhance error handling for MsSql * Refactor error handling for consistency * Enhance: Rest api body to accept raw input instead of raw json. (#2249) * Enhanced rest api body to accept raw input instead of raw json. * Changed content type from application/json to text/json and changed copywrite to RAW. * Changed rest api body toggle label from 'RAW' to 'Raw'. * Added request label for static REST API data source. * Fixed issue where GET query failed since body was undefined. * Integrated json_body to add backward compatibility. * Removed console logs. * Added support for 'text/json' type in checkIfContentTypeIsJson function. * Made changes according to new frontend architecture in v3. * Fixed request URL field overflow issue. --------- Co-authored-by: Akshay Sasidharan <akshaysasidharan93@gmail.com> * Feature: Add SSL support to MongoDB datasource (#2430) * Add TLS support inputs in frontend * Add backend logic for TLS support * Add TLS inputs types * Update TLS label * Change ssl_certificate to tls_certificate * Update the file handling in tls * Update connection logic * Fix unlinking file issue * Remove catch block for unlinking file * Handle tls certs directly * Feature: Stripe plugin UI fixes with OpenAPI endpoint as source (#2725) * Fixed GET and DELETE request input renders and added all UX fixes (#9498) * fixed get and delete request input renders and added all UX fixes * Extracted Stripe plugin component as a separate component for Dynamic Form. * Resolved PR review comments and fixed issue where rendering path input field crashed the app. * Changed param name underline to dashed for tooltip and revamped input field clear button * Fixed a few sonarlint issues. * Removed the duplicate code by creating a separate function named RenderParameterFields. * Refactored computeOperationSelectionOptions function to not nest functions more than 4 levels deep. * Refactored RenderParameterFields function to reduce its Cognitive Complexity. * Made span tag with the 'button' interactive role focusable. * Inside switch case for codehinter in DynamicForm > getElementProps, Extracted nested ternary operation for theme into an independent statement. * Added keyboard listener to the clear button. * Removed opacity from select dropdown and operation from operation select dropdown UI. * Fixed syntax error in clearButton function. * Removed the package @nrwl/nx-linux-x64-gnu from marketplace dependencies. --------- Co-authored-by: Mansukh Kaur <mansukhkaur@Mansukhs-MacBook-Pro.local> Co-authored-by: Devanshu Rastogi <devanshu.rastogi05@gmail.com> * Made changes according to new app builder architecture in v3. * Fixed import issue for codehintor * Fixed issue where due to incorrect value, stripe queries crashed the entire app. --------- Co-authored-by: Mansukh Kaur <mansukhkaur@Mansukhs-MacBook-Pro.local> Co-authored-by: Devanshu Rastogi <devanshu.rastogi05@gmail.com> * Enhance: Improve error handling in Airtable run query (#2234) * Refactor error handling to streamline QueryError messages * Handle 404 errors * Enhance: Add AI-tag to datasources in marketplace page (#2597) * Add AI-tag to datasources in marketplace page * AI BANNER Tag * margin * Refactor tag rendering logic for marketplace page * Refactor tag rendering for datasource page * Refactor import and props * Remove ai prefix and fix indentations * Make custom hook for fetching plugins.json * Add AI tag on installed page * Marketplace page UI fix and add a plugin button fixes * Add AI tag on datasource connection form Change classname * Fix svg flickering * Fix svg chipping issue * Push AI tag to extreme right --------- Co-authored-by: Rudra <rudra21ultra@gmail.com> * Fix: Api call for token generation in client-credentials grant type (#2785) * fix: query kind for select source in rest api * Fix: ToolJet database limit check API issue (#11416) * bump to v3.0.5-ce * Added data-cy for newly added components (#11435) * Modified failed Platform cypress test cases for Tooljet V3 (#11486) * Modify platform cypress test cases * Added cypress test cases for user onboarding flow (#11499) * Add data-cy for newly added components * Add data-cy for onboarding page elements * Modify failed test cases * Adding more cases * Modify onboarding test cases * Modify user invite flow * chnages on onboarding test scripts * revert the changes * revert the changes * removed .only form profile file * resolved review changes --------- Co-authored-by: ajith-k-v <ajith.jaban@gmail.com> Co-authored-by: Sri mani Teja s <mani@Sris-MacBook-Pro-4.local> * fix: Fixes broken loading state for container * update cypress workflow for subpath * Add data-cy for workspace constants components (#11530) * fix table down load event not showing up * Hotfix: The build failed to include the reference file for custom validation of the ToolJet database schema. (#11490) * tooljet database schema custom validation reference file was not included in the build * fix: missed a dependency for copyfiles * change version to 3.1.0 --------- Co-authored-by: Ganesh Kumar <ganesh8056234@gmail.com> Co-authored-by: Parth <108089718+parthy007@users.noreply.github.com> Co-authored-by: Devanshu Rastogi <devanshu.rastogi05@gmail.com> Co-authored-by: Akshay Sasidharan <akshaysasidharan93@gmail.com> Co-authored-by: Mansukh Kaur <mansukhkaur@Mansukhs-MacBook-Pro.local> Co-authored-by: Rudra <rudra21ultra@gmail.com> Co-authored-by: Vijaykant Yadav <vjy239@gmail.com> Co-authored-by: Ganesh Kumar <40178541+ganesh8056@users.noreply.github.com> Co-authored-by: Ajith KV <ajith.jaban@gmail.com> Co-authored-by: Adish M <44204658+adishM98@users.noreply.github.com> Co-authored-by: Srimanitejas123 <mani@tooljet.com> Co-authored-by: Sri mani Teja s <mani@Sris-MacBook-Pro-4.local> Co-authored-by: Nithin David Thomas <1277421+nithindavid@users.noreply.github.com> Co-authored-by: Kartik Gupta <gupta.kartik18kg@gmail.com>
This commit is contained in:
parent
3bf422d3cc
commit
97fb315019
131 changed files with 4444 additions and 4804 deletions
2
.github/workflows/cypress-platform.yml
vendored
2
.github/workflows/cypress-platform.yml
vendored
|
|
@ -212,7 +212,7 @@ jobs:
|
|||
uses: jsdaniell/create-json@1.1.2
|
||||
with:
|
||||
name: "cypress.env.json"
|
||||
json: ${{ secrets.CYPRESS_SECRETS }}
|
||||
json: ${{ secrets.CYPRESS_SECRETS_SUBPATH }}
|
||||
dir: "./cypress-tests"
|
||||
|
||||
- name: Platform-subpath
|
||||
|
|
|
|||
2
.version
2
.version
|
|
@ -1 +1 @@
|
|||
3.2.4-ce
|
||||
3.2.0-ce
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ module.exports = defineConfig({
|
|||
experimentalModfyObstructiveThirdPartyCode: true,
|
||||
experimentalRunAllSpecs: true,
|
||||
baseUrl: "http://localhost:8082",
|
||||
specPattern: "cypress/e2e/happyPath/platform/commonTestcases/**/*.cy.js",
|
||||
specPattern: "cypress/e2e/happyPath/platform/**/**/*.cy.js",
|
||||
downloadsFolder: "cypress/downloads",
|
||||
numTestsKeptInMemory: 0,
|
||||
redirectionLimit: 10,
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ Cypress.Commands.add(
|
|||
redirection = "/"
|
||||
) => {
|
||||
cy.request({
|
||||
url: `http://localhost:3000/api/authenticate/${workspaceId}`,
|
||||
url: `${Cypress.env("server_host")}/api/authenticate/${workspaceId}`,
|
||||
method: "POST",
|
||||
body: {
|
||||
email: userEmail,
|
||||
|
|
@ -69,7 +69,7 @@ Cypress.Commands.add("apiCreateApp", (appName = "testApp") => {
|
|||
Cypress.env("authToken", `tj_auth_token=${cookie.value}`);
|
||||
cy.request({
|
||||
method: "POST",
|
||||
url: "http://localhost:3000/api/apps",
|
||||
url: `${Cypress.env("server_host")}/api/apps`,
|
||||
headers: {
|
||||
"Tj-Workspace-Id": Cypress.env("workspaceId"),
|
||||
Cookie: `tj_auth_token = ${cookie.value}`,
|
||||
|
|
@ -103,7 +103,7 @@ Cypress.Commands.add("apiDeleteApp", (appId = Cypress.env("appId")) => {
|
|||
cy.request(
|
||||
{
|
||||
method: "DELETE",
|
||||
url: `http://localhost:3000/api/apps/${Cypress.env("appId")}`,
|
||||
url: `${Cypress.env("server_host")}/api/apps/${Cypress.env("appId")}`,
|
||||
headers: {
|
||||
"Tj-Workspace-Id": Cypress.env("workspaceId"),
|
||||
Cookie: Cypress.env("authToken"),
|
||||
|
|
@ -140,7 +140,7 @@ Cypress.Commands.add("apiCreateWorkspace", (workspaceName, workspaceSlug) => {
|
|||
cy.request(
|
||||
{
|
||||
method: "POST",
|
||||
url: "http://localhost:3000/api/organizations",
|
||||
url: `${Cypress.env("server_host")}/api/organizations`,
|
||||
headers: {
|
||||
"Tj-Workspace-Id": Cypress.env("workspaceId"),
|
||||
Cookie: `tj_auth_token=${cookie.value}`,
|
||||
|
|
@ -162,7 +162,7 @@ Cypress.Commands.add("logoutApi", () => {
|
|||
cy.request(
|
||||
{
|
||||
method: "GET",
|
||||
url: "http://localhost:3000/api/logout",
|
||||
url: `${Cypress.env("server_host")}/api/logout`,
|
||||
headers: {
|
||||
"Tj-Workspace-Id": Cypress.env("workspaceId"),
|
||||
Cookie: `tj_auth_token=${cookie.value}`,
|
||||
|
|
@ -180,7 +180,7 @@ Cypress.Commands.add("userInviteApi", (userName, userEmail) => {
|
|||
cy.request(
|
||||
{
|
||||
method: "POST",
|
||||
url: "http://localhost:3000/api/organization_users",
|
||||
url: `${Cypress.env("server_host")}/api/organization_users`,
|
||||
headers: {
|
||||
"Tj-Workspace-Id": Cypress.env("workspaceId"),
|
||||
Cookie: `tj_auth_token=${cookie.value}`,
|
||||
|
|
@ -207,7 +207,7 @@ Cypress.Commands.add("addQueryApi", (queryName, query, dataQueryId) => {
|
|||
};
|
||||
cy.request({
|
||||
method: "PATCH",
|
||||
url: `http://localhost:3000/api/data_queries/${dataQueryId}`,
|
||||
url: `${Cypress.env("server_host")}/api/data_queries/${dataQueryId}`,
|
||||
headers: headers,
|
||||
body: {
|
||||
name: queryName,
|
||||
|
|
@ -234,7 +234,7 @@ Cypress.Commands.add(
|
|||
|
||||
cy.request({
|
||||
method: "GET",
|
||||
url: `http://localhost:3000/api/apps/${appId}`,
|
||||
url: `${Cypress.env("server_host")}/api/apps/${appId}`,
|
||||
headers: {
|
||||
"Tj-Workspace-Id": workspaceId,
|
||||
Cookie: `${authToken}; app_id=${appId}`,
|
||||
|
|
@ -246,7 +246,7 @@ Cypress.Commands.add(
|
|||
|
||||
cy.request({
|
||||
method: "POST",
|
||||
url: "http://localhost:3000/api/data_queries",
|
||||
url: `${Cypress.env("server_host")}/api/data_queries`,
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Cookie: authToken,
|
||||
|
|
@ -273,3 +273,141 @@ Cypress.Commands.add(
|
|||
});
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
// Cypress.Commands.add("addComponentToApp", (appName, componentName, layoutConfig = {}) => {
|
||||
|
||||
|
||||
// cy.task("updateId", {
|
||||
// dbconfig: Cypress.env("app_db"),
|
||||
// sql: `select id from apps where name='${appName}';`,
|
||||
// }).then((resp) => {
|
||||
// appId = resp.rows[0]id;
|
||||
|
||||
|
||||
// // Default layout values
|
||||
// const defaultLayout = {
|
||||
// desktop: { top: 90, left: 9, width: 6, height: 40 },
|
||||
// mobile: { top: 90, left: 9, width: 6, height: 40 },
|
||||
// };
|
||||
|
||||
// // Merge default layout with the provided configuration
|
||||
// const layouts = {
|
||||
// desktop: { ...defaultLayout.desktop, ...layoutConfig.desktop },
|
||||
// mobile: { ...defaultLayout.mobile, ...layoutConfig.mobile },
|
||||
// };
|
||||
|
||||
// cy.getCookie("tj_auth_token", { log: false }).then((cookie) => {
|
||||
// Cypress.env("authToken", `tj_auth_token=${cookie.value}`);
|
||||
|
||||
// cy.request({
|
||||
// method: "GET",
|
||||
// url: `${Cypress.env("server_host")}/api/v2/apps/${appId}`,
|
||||
// headers: {
|
||||
// "Tj-Workspace-Id": Cypress.env("workspaceId"),
|
||||
// Cookie: `tj_auth_token=${cookie.value}`,
|
||||
// },
|
||||
// }).then((response) => {
|
||||
// expect(response.status).to.eq(200);
|
||||
|
||||
// const { id: editingVersionId, home_page_id: homePageId } = response.body.editing_version;
|
||||
// const componentId = crypto.randomUUID ? crypto.randomUUID() : require("uuid").v4();
|
||||
|
||||
// const requestBody = {
|
||||
// is_user_switched_version: false,
|
||||
// pageId: homePageId,
|
||||
// diff: {
|
||||
// [componentId]: {
|
||||
// name: componentName,
|
||||
// layouts: layouts,
|
||||
// type: "Text",
|
||||
// },
|
||||
// },
|
||||
// };
|
||||
|
||||
// cy.request({
|
||||
// method: "POST",
|
||||
// url: `${Cypress.env("server_host")}/api/v2/apps/$${appId}/versions/${editingVersionId}/components`,
|
||||
// headers: {
|
||||
// "Content-Type": "application/json",
|
||||
// "Tj-Workspace-Id": Cypress.env("workspaceId"),
|
||||
// Cookie: `tj_auth_token=${cookie.value}`,
|
||||
// },
|
||||
// body: requestBody,
|
||||
// }).then((postResponse) => {
|
||||
// expect(postResponse.status).to.eq(201);
|
||||
// cy.log(`Component ${componentId} added successfully`);
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
|
||||
Cypress.Commands.add("addComponentToApp", (appName, componentName, layoutConfig = {}) => {
|
||||
cy.task("updateId", {
|
||||
dbconfig: Cypress.env("app_db"),
|
||||
sql: `select id from apps where name='${appName}';`,
|
||||
}).then((resp) => {
|
||||
const appId = resp.rows[0]?.id; // Safely access the id field
|
||||
|
||||
if (!appId) {
|
||||
throw new Error(`App ID not found for appName: ${appName}`);
|
||||
}
|
||||
|
||||
// Default layout values
|
||||
const defaultLayout = {
|
||||
desktop: { top: 90, left: 9, width: 6, height: 40 },
|
||||
mobile: { top: 90, left: 9, width: 6, height: 40 },
|
||||
};
|
||||
|
||||
// Merge default layout with the provided configuration
|
||||
const layouts = {
|
||||
desktop: { ...defaultLayout.desktop, ...layoutConfig.desktop },
|
||||
mobile: { ...defaultLayout.mobile, ...layoutConfig.mobile },
|
||||
};
|
||||
|
||||
cy.getCookie("tj_auth_token", { log: false }).then((cookie) => {
|
||||
Cypress.env("authToken", `tj_auth_token=${cookie.value}`);
|
||||
|
||||
cy.request({
|
||||
method: "GET",
|
||||
url: `${Cypress.env("server_host")}/api/v2/apps/${appId}`,
|
||||
headers: {
|
||||
"Tj-Workspace-Id": Cypress.env("workspaceId"),
|
||||
Cookie: `tj_auth_token=${cookie.value}`,
|
||||
},
|
||||
}).then((response) => {
|
||||
expect(response.status).to.eq(200);
|
||||
|
||||
const { id: editingVersionId, home_page_id: homePageId } = response.body.editing_version;
|
||||
const componentId = crypto.randomUUID ? crypto.randomUUID() : require("uuid").v4();
|
||||
|
||||
const requestBody = {
|
||||
is_user_switched_version: false,
|
||||
pageId: homePageId,
|
||||
diff: {
|
||||
[componentId]: {
|
||||
name: componentName,
|
||||
layouts: layouts,
|
||||
type: "Text",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
cy.request({
|
||||
method: "POST",
|
||||
url: `${Cypress.env("server_host")}/api/v2/apps/${appId}/versions/${editingVersionId}/components`,
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Tj-Workspace-Id": Cypress.env("workspaceId"),
|
||||
Cookie: `tj_auth_token=${cookie.value}`,
|
||||
},
|
||||
body: requestBody,
|
||||
}).then((postResponse) => {
|
||||
expect(postResponse.status).to.eq(201);
|
||||
cy.log(`Component ${componentId} added successfully`);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -5,16 +5,23 @@ import { commonText, createBackspaceText } from "Texts/common";
|
|||
import { passwordInputText } from "Texts/passwordInput";
|
||||
import { importSelectors } from "Selectors/exportImport";
|
||||
import { importText } from "Texts/exportImport";
|
||||
import { onboardingSelectors } from "Selectors/onboarding";
|
||||
|
||||
Cypress.Commands.add(
|
||||
"login",
|
||||
"appUILogin",
|
||||
(email = "dev@tooljet.io", password = "password") => {
|
||||
cy.visit("/");
|
||||
cy.clearAndType(commonSelectors.workEmailInputField, email);
|
||||
cy.clearAndType(commonSelectors.passwordInputField, password);
|
||||
cy.get(commonSelectors.signInButton).click();
|
||||
cy.wait(2000);
|
||||
cy.get(commonSelectors.homePageLogo).should("be.visible");
|
||||
cy.wait(3000);
|
||||
cy.clearAndType(onboardingSelectors.loginEmailInput, email);
|
||||
cy.clearAndType(onboardingSelectors.loginPasswordInput, password);
|
||||
cy.get(onboardingSelectors.signInButton).click();
|
||||
|
||||
cy.intercept("GET", "api/library_apps").as(
|
||||
"library_apps"
|
||||
);
|
||||
cy.get(commonSelectors.homePageLogo, { timeout: 10000 });
|
||||
cy.wait("@library_apps");
|
||||
|
||||
}
|
||||
);
|
||||
|
||||
|
|
@ -90,14 +97,6 @@ Cypress.Commands.add(
|
|||
}
|
||||
);
|
||||
|
||||
Cypress.Commands.add("appUILogin", () => {
|
||||
cy.visit("/");
|
||||
cy.clearAndType(commonSelectors.workEmailInputField, "dev@tooljet.io");
|
||||
cy.clearAndType(commonSelectors.passwordInputField, "password");
|
||||
cy.get(commonSelectors.signInButton).click();
|
||||
cy.wait(2000);
|
||||
cy.get(commonSelectors.homePageLogo).should("be.visible");
|
||||
});
|
||||
|
||||
Cypress.Commands.add(
|
||||
"clearAndTypeOnCodeMirror",
|
||||
|
|
@ -365,11 +364,11 @@ Cypress.Commands.add("getPosition", (componentName) => {
|
|||
|
||||
Cypress.Commands.add("defaultWorkspaceLogin", () => {
|
||||
cy.apiLogin();
|
||||
cy.intercept("GET", "http://localhost:3000/api/library_apps").as(
|
||||
cy.intercept("GET", "/api/library_apps").as(
|
||||
"library_apps"
|
||||
);
|
||||
cy.visit("/my-workspace");
|
||||
cy.get(commonSelectors.homePageLogo, { timeout: 10000 });
|
||||
// cy.get(commonSelectors.homePageLogo, { timeout: 10000 });
|
||||
cy.wait("@library_apps");
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -5,10 +5,10 @@ export const cyParamName = (paramName = "") => {
|
|||
export const commonSelectors = {
|
||||
toastMessage: ".go3958317564",
|
||||
oldToastMessage: ".go318386747",
|
||||
newToastMessage:
|
||||
'.drawer-container > [style="position: fixed; z-index: 9999; inset: 16px; pointer-events: none;"] > .go4109123758 > .go2072408551',
|
||||
newToastMessage: '.drawer-container > [style="position: fixed; z-index: 9999; inset: 16px; pointer-events: none;"] > .go4109123758 > .go2072408551 > .go3958317564',
|
||||
toastCloseButton: '[data-cy="toast-close-button"]',
|
||||
editButton: "[data-cy=edit-button]",
|
||||
fileSelector: "[data-cy=uploaded-file-data]",
|
||||
searchField: "[data-cy='widget-search-box-search-bar']",
|
||||
firstWidget: "[data-cy=widget-list]:eq(0)",
|
||||
canvas: "[data-cy=real-canvas]",
|
||||
|
|
@ -21,9 +21,9 @@ export const commonSelectors = {
|
|||
workEmailLabel: '[data-cy="work-email-label"]',
|
||||
workEmailInputField: "[data-cy=work-email-input]",
|
||||
emailInputError: '[data-cy="email-error-message"]',
|
||||
passwordLabel: '[data-cy="password-label"]',
|
||||
passwordLabel: '[data-cy="password-input-label"]',
|
||||
forgotPasswordLink: '[data-cy="forgot-password-link"]',
|
||||
passwordInputField: '[data-cy="password-input-field"]',
|
||||
passwordInputField: '[data-cy="password-input-input"]',
|
||||
signInButton: "[data-cy=login-button]",
|
||||
loginButton: '[data-cy="login-button"]',
|
||||
dropdown: "[data-cy=workspace-dropdown]",
|
||||
|
|
@ -63,20 +63,21 @@ export const commonSelectors = {
|
|||
workspaceLoginUrl: "[data-cy=workspace-login-url]",
|
||||
workspaceName: '[data-cy="workspace-name"]:eq(0)',
|
||||
signInHeader: '[data-cy="sign-in-header"]',
|
||||
signInSubHeader: '[data-cy="sign-in-sub-header"]',
|
||||
signInSubHeader: '[data-cy="signup-info"]',
|
||||
createAnAccountLink: '[data-cy="create-an-account-link"]',
|
||||
SignUpSectionHeader: '[data-cy="signup-section-header"]',
|
||||
signUpSectionHeader: '[data-cy="sign-up-header"]',
|
||||
signInRedirectText: '[data-cy="signin-redirect-text"]',
|
||||
signInRedirectLink: '[data-cy="signin-redirect-link"]',
|
||||
signInRedirectLink: '[data-cy="signin-link"]',
|
||||
signUpTermsHelperText: '[data-cy="signup-terms-helper"]',
|
||||
termsOfServiceLink: '[data-cy="terms-of-service-link"]',
|
||||
privacyPolicyLink: '[data-cy="privacy-policy-link"]',
|
||||
redirectURL: '[data-cy="redirect-url"]',
|
||||
invitePageHeader: '[data-cy="invite-page-header"]',
|
||||
invitePageSubHeader: '[data-cy="invite-page-sub-header"]',
|
||||
invitePageHeader: '[data-cy="join-my-workspace-header"]',
|
||||
invitePageSubHeader: '[data-cy="onboarding-page-description"]',
|
||||
userNameInputLabel: '[data-cy="name-input-label"]',
|
||||
invitedUserName: '[data-cy="invited-user-name"]',
|
||||
invitedUserEmail: '[data-cy="invited-user-email"]',
|
||||
invitedUserName: '[data-cy="name-input-input-value"]',
|
||||
invitedUserEmail: '[data-cy="email-input-value"]',
|
||||
invitedUseremail: '[data-cy="email-input-input-value"]',
|
||||
acceptInviteButton: '[data-cy="accept-invite-button"]',
|
||||
databaseIcon: '[data-cy="icon-database"]',
|
||||
profileSettings: '[data-cy="profile-settings"]',
|
||||
|
|
@ -108,6 +109,9 @@ export const commonSelectors = {
|
|||
exportAllButton: '[data-cy="export-all-button"]',
|
||||
avatarImage: '[data-cy="avatar-image"]',
|
||||
selfHostSetUpBanner: '[data-cy="setup-banner-inner"]',
|
||||
HostBanner: '[data-cy="onboarding-image"]',
|
||||
adminSetup: '[data-cy="set-up-your-admin-account-header"]',
|
||||
signupTerms: '[data-cy="signup-terms-helper"]',
|
||||
selfHostSetUpSubBanner: '[data-cy="setup-sub-banner"]',
|
||||
selfHostSetUpCard: '[data-cy="setup-card"]',
|
||||
selfHostSetUpCardImage: '[data-cy="setup-card-image"]',
|
||||
|
|
@ -115,52 +119,58 @@ export const commonSelectors = {
|
|||
selfHostSetUpCardSubHeader: '[data-cy="setup-card-sub-header"]',
|
||||
setUpToolJetButton: '[data-cy="setup-tooljet-button"]',
|
||||
setUpadminCheckPoint: '[data-cy="set-up-admin-check-point"]',
|
||||
setUpworkspaceCheckPoint: '[data-cy="set-up-workspace-check-point"]',
|
||||
setUpworkspaceCheckPoint: '[data-cy="set-up-your-workspace!-header"]',
|
||||
companyProfileCheckPoint: '[data-cy="company-profile-check-point"]',
|
||||
onboardingPageHeader: '[data-cy="onboarding-page-header"]',
|
||||
onboardingPageSubHeader: '[data-cy="onboarding-page-sub-header"]',
|
||||
onboardingPageDescription: '[data-cy="onboarding-page-description"]',
|
||||
passwordHelperText: '[data-cy="password-helper-text"]',
|
||||
passwordHelperText: '[data-cy="new-password-input-hint"]',
|
||||
continueButton: '[data-cy="continue-button"]',
|
||||
passwordHelperTextSignup: '[data-cy="password-input-hint"]',
|
||||
continueButton: '[data-cy="sign-up-button"]',
|
||||
OnbordingContinue: '[data-cy="onboarding-submit-button"]',
|
||||
userAccountNameAvatar: '[data-cy="user-account-name-avatar"]',
|
||||
workspaceNameInputLabel: '[data-cy="workspace-name-input-label"]',
|
||||
workspaceNameInputField: '[data-cy="workspace-name-input-field"]',
|
||||
workspaceNameInputLabel: '[data-cy="onboarding-workspace-name-label"]',
|
||||
workspaceNameInputField: '[data-cy="onboarding-workspace-name-input"]',
|
||||
backArrow: '[data-cy="back-arrow"]',
|
||||
backArrowText: '[data-cy="back-arrow-text"]',
|
||||
onboardingPorgressBubble: '[data-cy="onboarding-progress-bubbles"]',
|
||||
skipArrow: '[data-cy="skip-button"]',
|
||||
skipArrowText: '[data-cy="skip-arrow-text"]',
|
||||
companyNameInputField: '[data-cy="company-name-input-field"]',
|
||||
nameInputField: '[data-cy="name-input-field"]',
|
||||
emailInputField: '[data-cy="email-input-field"]',
|
||||
nameInputField: '[data-cy="name-input-input"]',
|
||||
emailInputField: '[data-cy="email-input-input"]',
|
||||
skipbutton: '[class="driver-close-btn"]',
|
||||
backLogo: '[data-cy="editor-page-logo"]',
|
||||
backtoapps: '[data-cy="back-to-app-option"]',
|
||||
signUpButton: '[data-cy="sign-up-button"]',
|
||||
emailImage: '[data-cy="email-image"]',
|
||||
spamMessage: '[data-cy="email-page-spam-msg"]',
|
||||
resendEmailButton: '[data-cy="resend-email-button"]',
|
||||
spamMessage: '[data-cy="info-message"]',
|
||||
resendEmailButton: '[data-cy="resend-verification-email-button"]',
|
||||
editEmailButton: '[data-cy="edit-email-button"]',
|
||||
createAccountCheckMark: '[data-cy="create-account-check-mark"]',
|
||||
createAccountCheckPoint: '[data-cy="create-account-check-point"]',
|
||||
verifyEmailCheckMark: '[data-cy="verify-email-check-mark"]',
|
||||
verifyEmailCheckPoint: '[data-cy="verify-email-check-point"]',
|
||||
backtoSignUpButton: '[data-cy="back-to-signup-button"]',
|
||||
forgotPasswordPageHeader: '[data-cy="forgot-password-page-header"]',
|
||||
forgotPasswordPageSubHeader: '[data-cy="forgot-password-sub-header"]',
|
||||
resetPasswordLinkButton: '[data-cy="reset-password-link"]',
|
||||
forgotPasswordPageHeader: '[data-cy="forgot-password-header"]',
|
||||
forgotPasswordPageSubHeader: '[data-cy="signup-redirect-text"]',
|
||||
resetPasswordLinkButton: '[data-cy="send-a-reset-link-button"]',
|
||||
enterIcon: '[data-cy="enter-icon"]',
|
||||
passwordResetPageHeader: '[data-cy="reset-password-page-header"]',
|
||||
passwordResetPageHeader: '[data-cy="reset-password-header"]',
|
||||
newPasswordInputLabel: '[data-cy="new-password-input-label"]',
|
||||
newPasswordInputField: '[data-cy="new-password-input-field"]',
|
||||
newPasswordInputField: '[data-cy="new-password-input-input"]',
|
||||
confirmPasswordInputFieldLabel: '[data-cy="confirm-password-input-label"]',
|
||||
confirmPasswordInputField: '[data-cy="confirm-password-input-field"]',
|
||||
confirmPasswordInputField: '[data-cy="confirm-password-input-input"]',
|
||||
resetPasswordButton: '[data-cy="reset-password-button"]',
|
||||
resetPasswordPageDescription: '[data-cy="reset-password-page-description"]',
|
||||
backToLoginButton: '[data-cy="back-to-login-button"]',
|
||||
backToLoginButton: '[data-cy="back-to-login"]',
|
||||
breadcrumbTitle: '[data-cy="app-header-label"]>>',
|
||||
breadcrumbPageTitle: '[data-cy="breadcrumb-page-title"]',
|
||||
labelFullNameInput: '[data-cy="label-full-name-input-field"]',
|
||||
inputFieldFullName: '[data-cy="input-field-full-name"]',
|
||||
labelEmailInput: '[data-cy="label-email-input-field"]',
|
||||
inputFieldEmailAddress: '[data-cy="input-field-email"]',
|
||||
labelFullNameInput: '[data-cy="name-label"]',
|
||||
inputFieldFullName: '[data-cy="name-input"]',
|
||||
labelEmailInput: '[data-cy="email-label"]',
|
||||
inputFieldEmailAddress: '[data-cy="email-input"]',
|
||||
closeButton: '[data-cy="close-button"]',
|
||||
emptyAppCreateButton: "[data-cy='button-new-app-from-scratch']",
|
||||
globalDataSourceIcon: '[data-cy="icon-global-datasources"]',
|
||||
|
|
@ -212,7 +222,7 @@ export const commonSelectors = {
|
|||
return `[data-cy="${cyParamName(folderName)}-edit-folder-option"]`;
|
||||
},
|
||||
inspectorPinIcon: '.d-flex > [data-cy="left-sidebar-inspector"]',
|
||||
groupInputFieldLabel: '[data-cy="label-group-input-field"]',
|
||||
groupInputFieldLabel: '[data-cy="user-group-label"]',
|
||||
pageSectionHeader: '[data-cy="dashboard-section-header"]',
|
||||
yesButton: '[data-cy="yes-button"]',
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ export const dashboardSelector = {
|
|||
ManageSSO: "[data-cy=manage-sso]",
|
||||
userMenu: "[data-cy=user-menu]",
|
||||
profileLink: "[data-cy=profile-link]",
|
||||
logoutLink: "[data-cy=logout-link]",
|
||||
logoutLink: '[data-cy="logout-link"]',
|
||||
changeIconTitle: "[data-cy=change-icon-title]",
|
||||
appCardDefaultIcon: "[data-cy=app-card-apps-icon]",
|
||||
changeButton: "[data-cy=change-button]",
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ export const ssoSelector = {
|
|||
redirectUrl: "[data-cy=redirect-url]",
|
||||
googleTile: '[data-cy="google-sign-in-text"]',
|
||||
googleIcon: "[data-cy=google-sso-icon]",
|
||||
googleSSOText: "[data-cy=google-sso-text]",
|
||||
googleSSOText: "[data-cy=google-sso-button-text]",
|
||||
git: '[data-cy="github-sso-card"]',
|
||||
gitEnableToggle: '[data-cy="github-toggle-input"]',
|
||||
githubLabel: '[data-cy="github-label"]',
|
||||
|
|
@ -43,7 +43,7 @@ export const ssoSelector = {
|
|||
gitTile: "[data-cy=git-tile]",
|
||||
gitIcon: "[data-cy=git-sso-icon]",
|
||||
gitSignInText: "[data-cy=git-sso-text]",
|
||||
gitSSOText: "[data-cy=git-sso-text]",
|
||||
gitSSOText: "[data-cy=git-sso-button-text]",
|
||||
password: "[data-cy=left-menu-items] :eq(3)",
|
||||
passwordEnableToggle: '[data-cy="password-enable-toggle"]',
|
||||
loginHelpText: "[data-cy=login-help-text]",
|
||||
|
|
|
|||
|
|
@ -62,10 +62,7 @@ export const usersSelector = {
|
|||
inputFieldBulkUpload: '[data-cy="input-field-bulk-upload"]',
|
||||
copyInvitationLink: '[data-cy="copy-invitation-link"]',
|
||||
uploadedFileData: '[data-cy="uploaded-file-data"]',
|
||||
toastCloseButton:
|
||||
'.drawer-container > [style="position: fixed; z-index: 9999; inset: 16px; pointer-events: none;"] > .go4109123758 > .go2072408551 > [data-cy="toast-close-button"]',
|
||||
|
||||
|
||||
toastCloseButton:'.drawer-container > [style="position: fixed; z-index: 9999; inset: 16px; pointer-events: none;"] > .go4109123758 > .go2072408551 > [data-cy="toast-close-button"]',
|
||||
userName: (userName) => {
|
||||
return `[data-cy="${cyParamName(userName)}-user-name"]`;
|
||||
},
|
||||
|
|
|
|||
20
cypress-tests/cypress/constants/selectors/onboarding.js
Normal file
20
cypress-tests/cypress/constants/selectors/onboarding.js
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
export const cyParamName = (paramName = "") => {
|
||||
return paramName.toLowerCase().replace(/\s+/g, "-");
|
||||
};
|
||||
|
||||
export const onboardingSelectors = {
|
||||
emailLabel: "[data-cy='email-label']",
|
||||
emailInput: "[data-cy='email-input-input']",
|
||||
signupEmailInput: "[data-cy='email-input']",
|
||||
loginEmailInput: "[data-cy='email-input']",
|
||||
passwordLabel: "[data-cy='password-label']",
|
||||
passwordInput: "[data-cy='password-input-input']",
|
||||
loginPasswordInput: "[data-cy='password-input']",
|
||||
signInButton: "[data-cy='sign-in-button']",
|
||||
passwordError: "[data-cy='password-error']",
|
||||
nameInput: "[data-cy='name-input']",
|
||||
nameLabel: '[data-cy="name-input-label"]',
|
||||
signupNameLabel: '[data-cy="name-label"]',
|
||||
forgotEmailInput: '[data-cy="email-input-field-input"]',
|
||||
createAnAccountLink: '[data-cy="create-an-account-link"]',
|
||||
}
|
||||
|
|
@ -52,13 +52,14 @@ export const commonText = {
|
|||
},
|
||||
closeButton: "modal close",
|
||||
workEmailLabel: "Email",
|
||||
emailInputError: "Invalid Email",
|
||||
passwordLabel: "Password",
|
||||
emailInputError: "Email is invalid",
|
||||
passwordLabel: "Password *",
|
||||
LoginPasswordLabel: "Password",
|
||||
forgotPasswordLink: "Forgot?",
|
||||
loginButton: " Login",
|
||||
signInHeader: "Sign in",
|
||||
signInSubHeader: "New to ToolJet?Create an account",
|
||||
SignUpSectionHeader: "Join ToolJet",
|
||||
signUpSectionHeader: "Join ToolJet",
|
||||
signInRedirectText: "Already have an account?",
|
||||
signInRedirectLink: "Sign in",
|
||||
signUpTermsHelperText: "By signing up you are agreeing to the",
|
||||
|
|
@ -67,11 +68,11 @@ export const commonText = {
|
|||
invitePageHeader: "Join My workspace",
|
||||
invitePageSubHeader:
|
||||
"You are invited to a workspace My workspace. Accept the invite to join the workspace.",
|
||||
userNameInputLabel: "Name",
|
||||
acceptInviteButton: "Accept invite",
|
||||
userNameInputLabel: "Name *",
|
||||
acceptInviteButton: "Accept Invite",
|
||||
createButton: "Create",
|
||||
saveChangesButton: "Save changes",
|
||||
emailInputLabel: "Email",
|
||||
emailInputLabel: "Email *",
|
||||
allApplicationLink: "All apps",
|
||||
notificationsCardTitle: "Notifications",
|
||||
emptyNotificationTitle: "You're all caught up!",
|
||||
|
|
@ -86,7 +87,7 @@ export const commonText = {
|
|||
"Let’s set up your workspace to get started with ToolJet",
|
||||
setUpToolJetButton: "Set up ToolJet",
|
||||
setUpadminCheckPoint: "Set up admin",
|
||||
setUpworkspaceCheckPoint: "Set up workspace",
|
||||
setUpworkspaceCheckPoint: "Set up your workspace!",
|
||||
companyProfileCheckPoint: "Company profile",
|
||||
setUpAdminHeader: "Set up your admin account",
|
||||
onboardingPageSubHeader: "This information will help us improve ToolJet.",
|
||||
|
|
@ -94,17 +95,18 @@ export const commonText = {
|
|||
continueButton: "Continue",
|
||||
resetPasswordButton: "Reset password",
|
||||
setUpWorkspaceHeader: "Set up your workspace",
|
||||
loginPasswordLabel: "Password *",
|
||||
userRolePageHeader: "What best describes your role?",
|
||||
sizeOftheCompanyHeader: "What is the size of your company?",
|
||||
workspaceNameInputLabel: "Workspace name",
|
||||
workspaceNameInputLabel: "Workspace name *",
|
||||
onboardingSeperatorText: "OR",
|
||||
getStartedButton: "Get started for free",
|
||||
emailPageHeader: "Check your mail",
|
||||
spamMessage: "Did not receive an email? Check your spam folder.",
|
||||
spamMessage: "Did not receive an email? Check your spam folder!",
|
||||
resendEmailButton: "Resend verification mail",
|
||||
editEmailButton: "Edit email address",
|
||||
emailVerifiedText: "Successfully verified email",
|
||||
continueToSetUp: "Continue to set up your workspace to start using ToolJet.",
|
||||
continueToSetUp: "Set up workspaces to manage users, applications & resources across various teams",
|
||||
createAccountCheckPoint: "Create account",
|
||||
verifyEmailCheckPoint: "Verify email",
|
||||
inalidInvitationLinkHeader: "Invalid verification link",
|
||||
|
|
@ -114,15 +116,15 @@ export const commonText = {
|
|||
forgotPasswordPageHeader: "Forgot Password",
|
||||
newToTooljetText: "New to ToolJet?",
|
||||
emailAddressLabel: "Email address",
|
||||
resetPasswordLinkButton: " Send a reset link",
|
||||
resetPasswordLinkButton: "Send a reset link",
|
||||
passwordResetEmailToast:
|
||||
"Please check your email/inbox for the password reset link",
|
||||
"Please check your email for the password reset link",
|
||||
passwordResetPageHeader: "Reset Password",
|
||||
passwordResetSuccessPageHeader: "Password has been reset",
|
||||
newPasswordInputLabel: "New Password",
|
||||
confirmPasswordInputFieldLabel: "Re-enter the password",
|
||||
newPasswordInputLabel: "New Password *",
|
||||
confirmPasswordInputFieldLabel: "Re-enter the password *",
|
||||
passwordResetSuccessToast: "Password reset successfully",
|
||||
backToLoginButton: "Back to log in",
|
||||
backToLoginButton: "Back to login",
|
||||
resetPasswordPageDescription:
|
||||
"Your password has been reset successfully, log into ToolJet to continue your session",
|
||||
labelFullNameInput: "Enter full name",
|
||||
|
|
@ -135,13 +137,13 @@ export const commonText = {
|
|||
addNewDataSourceButton: "Add new datasource",
|
||||
|
||||
emailPageDescription: (email) => {
|
||||
return `We’ve sent an email to ${email} with a verification link. Please use that to verify your email address.`;
|
||||
return `We've sent a verification email to ${email}. Click the link inside to confirm your email and continue. This helps us ensure account security.`
|
||||
},
|
||||
companyPageHeader: (userName) => {
|
||||
return `Where do you work ${userName}?`;
|
||||
},
|
||||
resetPasswordEmailDescription: (email) => {
|
||||
return `We’ve sent an email to ${email} with a password reset link. Please click on that link to reset your password.`;
|
||||
return `We've sent a password reset link to ${email}. Click the link inside to reset your password and continue.`;
|
||||
},
|
||||
userJobRole: {
|
||||
HeadOfEngineering: "Head of engineering",
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ describe("App slug", () => {
|
|||
);
|
||||
cy.url().should(
|
||||
"eq",
|
||||
`http://localhost:8082/my-workspace/apps/${data.slug}/home`
|
||||
`http://localhost:8082/my-workspace/apps/${data.slug}`
|
||||
);
|
||||
|
||||
releaseApp();
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import { addAppToGroup } from "Support/utils/manageGroups";
|
|||
import { ssoSelector } from "Selectors/manageSSO";
|
||||
import { fetchAndVisitInviteLink } from "Support/utils/manageUsers";
|
||||
import { usersSelector } from "Selectors/manageUsers";
|
||||
import { onboardingSelectors } from "Selectors/onboarding";
|
||||
|
||||
describe(
|
||||
"App share functionality",
|
||||
|
|
@ -26,7 +27,6 @@ describe(
|
|||
const data = {};
|
||||
beforeEach(() => {
|
||||
cy.defaultWorkspaceLogin();
|
||||
// cy.removeAssignedApps();
|
||||
cy.skipWalkthrough();
|
||||
});
|
||||
|
||||
|
|
@ -36,16 +36,19 @@ describe(
|
|||
|
||||
cy.apiCreateApp(data.appName);
|
||||
cy.openApp();
|
||||
cy.dragAndDropWidget("Table", 250, 250);
|
||||
cy.addComponentToApp(data.appName, "text1");
|
||||
|
||||
verifyTooltip(
|
||||
commonWidgetSelector.shareAppButton,
|
||||
"Share URL is unavailable until current version is released"
|
||||
);
|
||||
cy.get('[data-cy="share-button-link"]>span').should(
|
||||
"have.class",
|
||||
"share-disabled"
|
||||
);
|
||||
//Need to automate with the new flow
|
||||
|
||||
// verifyTooltip(
|
||||
// commonWidgetSelector.shareAppButton,
|
||||
// "Share URL is unavailable until current version is released"
|
||||
// );
|
||||
|
||||
// cy.get('[data-cy="share-button-link"]>span').should(
|
||||
// "have.class",
|
||||
// "share-disabled"
|
||||
// );
|
||||
releaseApp();
|
||||
cy.get(commonWidgetSelector.shareAppButton).click();
|
||||
|
||||
|
|
@ -72,7 +75,7 @@ describe(
|
|||
|
||||
logout();
|
||||
cy.wait(4000);
|
||||
cy.get(commonSelectors.loginButton, { timeout: 20000 }).should(
|
||||
cy.get(onboardingSelectors.signInButton, { timeout: 20000 }).should(
|
||||
"be.visible"
|
||||
);
|
||||
cy.visitSlug({
|
||||
|
|
@ -80,22 +83,22 @@ describe(
|
|||
});
|
||||
cy.wait(3000);
|
||||
|
||||
cy.get(commonSelectors.loginButton, { timeout: 20000 }).should(
|
||||
cy.get(onboardingSelectors.signInButton, { timeout: 20000 }).should(
|
||||
"be.visible"
|
||||
);
|
||||
|
||||
cy.clearAndType(commonSelectors.workEmailInputField, "dev@tooljet.io");
|
||||
cy.clearAndType(commonSelectors.passwordInputField, "password");
|
||||
cy.get(commonSelectors.loginButton).click();
|
||||
cy.clearAndType(onboardingSelectors.emailInput, "dev@tooljet.io");
|
||||
cy.clearAndType(onboardingSelectors.passwordInput, "password");
|
||||
cy.get(onboardingSelectors.signInButton).click();
|
||||
|
||||
cy.wait(500);
|
||||
cy.get('[data-cy="draggable-widget-table1"]').should("be.visible");
|
||||
cy.get(".text-widget-section > div").should("be.visible");
|
||||
cy.get(commonSelectors.viewerPageLogo).click();
|
||||
|
||||
cy.openApp(
|
||||
"my-workspace",
|
||||
Cypress.env("appId"),
|
||||
'[data-cy="draggable-widget-table1"]'
|
||||
".text-widget-section > div"
|
||||
);
|
||||
cy.get(commonWidgetSelector.shareAppButton).click();
|
||||
cy.get(commonWidgetSelector.makePublicAppToggle).check();
|
||||
|
|
@ -104,23 +107,22 @@ describe(
|
|||
|
||||
logout();
|
||||
cy.wait(4000);
|
||||
cy.get(commonSelectors.loginButton, { timeout: 20000 }).should(
|
||||
cy.get(onboardingSelectors.signInButton, { timeout: 20000 }).should(
|
||||
"be.visible"
|
||||
);
|
||||
cy.visitSlug({
|
||||
actualUrl: `http://localhost:8082/applications/${data.slug}`,
|
||||
});
|
||||
cy.wait(3000);
|
||||
cy.get('[data-cy="draggable-widget-table1"]').should("be.visible");
|
||||
cy.get(".text-widget-section > div").should("be.visible");
|
||||
});
|
||||
|
||||
it("Verify app private and public app visibility for the same workspace user", () => {
|
||||
data.appName = `${fake.companyName} App`;
|
||||
data.slug = data.appName.toLowerCase().replace(/\s+/g, "-");
|
||||
|
||||
cy.apiCreateApp(data.appName);
|
||||
cy.openApp();
|
||||
cy.dragAndDropWidget("Table", 250, 250);
|
||||
cy.addComponentToApp(data.appName, "text1");
|
||||
releaseApp();
|
||||
|
||||
cy.wait(1000);
|
||||
|
|
@ -132,13 +134,13 @@ describe(
|
|||
cy.backToApps();
|
||||
|
||||
cy.visitSlug({ actualUrl: `/applications/${data.slug}` });
|
||||
cy.get('[data-cy="draggable-widget-table1"]').should("be.visible");
|
||||
cy.get(".text-widget-section > div").should("be.visible");
|
||||
|
||||
cy.defaultWorkspaceLogin();
|
||||
cy.openApp(
|
||||
"my-workspace",
|
||||
Cypress.env("appId"),
|
||||
'[data-cy="draggable-widget-table1"]'
|
||||
".text-widget-section > div"
|
||||
);
|
||||
cy.wait(2000);
|
||||
cy.get(commonWidgetSelector.shareAppButton).click();
|
||||
|
|
@ -149,20 +151,21 @@ describe(
|
|||
|
||||
logout();
|
||||
cy.wait(4000);
|
||||
cy.get(commonSelectors.loginButton, { timeout: 20000 }).should(
|
||||
cy.get(onboardingSelectors.signInButton, { timeout: 20000 }).should(
|
||||
"be.visible"
|
||||
);
|
||||
|
||||
cy.visitSlug({ actualUrl: `/applications/${data.slug}` });
|
||||
|
||||
cy.login("test@tooljet.com", "password");
|
||||
cy.appUILogin("test@tooljet.com", "password");
|
||||
cy.get(commonSelectors.allApplicationLink).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.allApplicationLink
|
||||
);
|
||||
});
|
||||
|
||||
it("Verify app private and public app visibility for the same instance user", () => {
|
||||
//Fix the case after bug fix
|
||||
it.skip("Verify app private and public app visibility for the same instance user", () => {
|
||||
data.firstName = fake.firstName;
|
||||
data.email = fake.email.toLowerCase();
|
||||
data.appName = `${fake.companyName} App`;
|
||||
|
|
@ -171,7 +174,8 @@ describe(
|
|||
|
||||
cy.apiCreateApp(data.appName);
|
||||
cy.openApp();
|
||||
cy.dragAndDropWidget("Table", 250, 250);
|
||||
cy.addComponentToApp(data.appName, "text1");
|
||||
|
||||
releaseApp();
|
||||
|
||||
cy.wait(1000);
|
||||
|
|
@ -183,13 +187,19 @@ describe(
|
|||
cy.logoutApi();
|
||||
userSignUp(data.firstName, data.email, data.workspaceName);
|
||||
cy.wait(3000);
|
||||
cy.backToApps();
|
||||
cy.wait(1000);
|
||||
|
||||
cy.visitSlug({ actualUrl: `/applications/${data.slug}` });
|
||||
cy.wait(1000);
|
||||
cy.pause();
|
||||
|
||||
cy.clearAndType(commonSelectors.workEmailInputField, data.email);
|
||||
cy.clearAndType(commonSelectors.passwordInputField, "password");
|
||||
cy.get(commonSelectors.signInButton).click();
|
||||
// logout();
|
||||
|
||||
cy.clearAndType(onboardingSelectors.emailInput, data.email);
|
||||
cy.clearAndType(onboardingSelectors.passwordInput, "password");
|
||||
cy.get(onboardingSelectors.signInButton).click();
|
||||
cy.pause();
|
||||
cy.wait(1000);
|
||||
cy.get(ssoSelector.workspaceSubHeader).verifyVisibleElement(
|
||||
"have.text",
|
||||
|
|
@ -211,15 +221,16 @@ describe(
|
|||
|
||||
logout();
|
||||
cy.wait(4000);
|
||||
cy.get(commonSelectors.loginButton, { timeout: 20000 }).should(
|
||||
cy.get(onboardingSelectors.signInButton, { timeout: 20000 }).should(
|
||||
"be.visible"
|
||||
);
|
||||
cy.visitSlug({ actualUrl: `/applications/${data.slug}` });
|
||||
cy.get('[data-cy="draggable-widget-table1"]').should("be.visible");
|
||||
cy.get(".text-widget-section > div").should("be.visible");
|
||||
cy.get(commonSelectors.viewerPageLogo).click();
|
||||
});
|
||||
|
||||
it("hould redirect to the workspace login page, allow signup, proceed to accept invite page, and load the app", () => {
|
||||
//Need to update with the new permission flow
|
||||
it.skip("hould redirect to the workspace login page, allow signup, proceed to accept invite page, and load the app", () => {
|
||||
let invitationToken,
|
||||
organizationToken,
|
||||
workspaceId,
|
||||
|
|
@ -235,7 +246,8 @@ describe(
|
|||
setSignupStatus(true);
|
||||
cy.apiCreateApp(data.appName);
|
||||
cy.openApp();
|
||||
cy.dragAndDropWidget("Table", 250, 250);
|
||||
cy.addComponentToApp(data.appName, "text1");
|
||||
|
||||
releaseApp();
|
||||
|
||||
cy.wait(1000);
|
||||
|
|
@ -258,8 +270,8 @@ describe(
|
|||
cy.get(commonSelectors.createAnAccountLink).click();
|
||||
|
||||
cy.clearAndType(commonSelectors.nameInputField, data.firstName);
|
||||
cy.clearAndType(commonSelectors.emailInputField, data.email);
|
||||
cy.clearAndType(commonSelectors.passwordInputField, commonText.password);
|
||||
cy.clearAndType(onboardingSelectors.emailInput, data.email);
|
||||
cy.clearAndType(onboardingSelectors.passwordInput, commonText.password);
|
||||
cy.get(commonSelectors.signUpButton).click();
|
||||
|
||||
cy.apiLogin();
|
||||
|
|
@ -296,7 +308,7 @@ describe(
|
|||
});
|
||||
});
|
||||
|
||||
cy.get('[data-cy="draggable-widget-table1"]').should("be.visible");
|
||||
cy.get(".text-widget-section > div").should("be.visible");
|
||||
});
|
||||
}
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,166 +0,0 @@
|
|||
import { commonSelectors } from "Selectors/common";
|
||||
import { commonText } from "Texts/common";
|
||||
import * as signup from "Support/utils/selfHostSignUp";
|
||||
import { logout } from "Support/utils/common";
|
||||
|
||||
describe("Self host onboarding", () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/setup');
|
||||
});
|
||||
|
||||
it("verify elements on self host onboarding page", () => {
|
||||
cy.get(commonSelectors.selfHostSetUpBanner).should("be.visible");
|
||||
cy.get(commonSelectors.selfHostSetUpSubBanner).should("be.visible");
|
||||
cy.get(commonSelectors.selfHostSetUpCard).should("be.visible");
|
||||
cy.get(commonSelectors.selfHostSetUpCardImage).should("be.visible");
|
||||
cy.get(commonSelectors.selfHostSetUpCardHeader).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.selfHostSetUpCardHeader
|
||||
);
|
||||
cy.get(commonSelectors.selfHostSetUpCardSubHeader).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.selfHostSetUpCardSubHeader
|
||||
);
|
||||
cy.get(commonSelectors.setUpToolJetButton)
|
||||
.verifyVisibleElement("have.text", commonText.setUpToolJetButton)
|
||||
.click();
|
||||
|
||||
signup.selfHostCommonElements();
|
||||
cy.get(commonSelectors.onboardingPageHeader).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.setUpAdminHeader
|
||||
);
|
||||
|
||||
cy.get(commonSelectors.userNameInputLabel).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.userNameInputLabel
|
||||
);
|
||||
cy.get(commonSelectors.nameInputField).should("be.visible");
|
||||
cy.get(commonSelectors.emailInputLabel).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.emailInputLabel
|
||||
);
|
||||
cy.get(commonSelectors.emailInputField).should("be.visible");
|
||||
cy.get(commonSelectors.passwordLabel).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.passwordLabel
|
||||
);
|
||||
cy.get(commonSelectors.passwordInputField).should("be.visible");
|
||||
|
||||
cy.get(commonSelectors.passwordHelperText).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.passwordHelperText
|
||||
);
|
||||
|
||||
cy.get(commonSelectors.signUpTermsHelperText).should(($el) => {
|
||||
expect($el.contents().first().text().trim()).to.eq(
|
||||
commonText.selfHostSignUpTermsHelperText
|
||||
);
|
||||
});
|
||||
cy.get(commonSelectors.termsOfServiceLink)
|
||||
.verifyVisibleElement("have.text", commonText.termsOfServiceLink)
|
||||
.and("have.attr", "href")
|
||||
.and("equal", "https://www.tooljet.com/terms");
|
||||
cy.get(commonSelectors.privacyPolicyLink)
|
||||
.verifyVisibleElement("have.text", commonText.privacyPolicyLink)
|
||||
.and("have.attr", "href")
|
||||
.and("equal", "https://www.tooljet.com/privacy");
|
||||
|
||||
cy.clearAndType(commonSelectors.nameInputField, "The Developer");
|
||||
cy.clearAndType(commonSelectors.emailInputField, "dev@tooljet.io");
|
||||
cy.clearAndType(commonSelectors.passwordInputField, "password");
|
||||
cy.get(commonSelectors.continueButton).click();
|
||||
|
||||
signup.selfHostCommonElements();
|
||||
cy.get(commonSelectors.userAccountNameAvatar).should("be.visible");
|
||||
cy.get(commonSelectors.onboardingPageHeader).verifyVisibleElement(
|
||||
"have.text",
|
||||
"Set up your workspace"
|
||||
);
|
||||
cy.get(commonSelectors.workspaceNameInputLabel).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.workspaceNameInputLabel
|
||||
);
|
||||
cy.get(commonSelectors.workspaceNameInputField).should("be.visible");
|
||||
cy.clearAndType(commonSelectors.workspaceNameInputField, "My workspace");
|
||||
cy.get(commonSelectors.continueButton).click();
|
||||
|
||||
signup.selfHostCommonElements();
|
||||
signup.commonElementsWorkspaceSetup();
|
||||
cy.get(commonSelectors.onboardingPageHeader).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.companyPageHeader("The Developer")
|
||||
);
|
||||
cy.get(commonSelectors.companyNameInputField).should("be.visible");
|
||||
cy.clearAndType(commonSelectors.companyNameInputField, "ToolJet");
|
||||
cy.get(commonSelectors.continueButton).click();
|
||||
|
||||
signup.selfHostCommonElements();
|
||||
signup.commonElementsWorkspaceSetup();
|
||||
cy.get(commonSelectors.onboardingPageHeader).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.userRolePageHeader
|
||||
);
|
||||
signup.verifyandModifyUserRole();
|
||||
|
||||
signup.selfHostCommonElements();
|
||||
signup.commonElementsWorkspaceSetup();
|
||||
cy.get(commonSelectors.onboardingPageHeader).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.sizeOftheCompanyHeader
|
||||
);
|
||||
|
||||
signup.verifyandModifySizeOftheCompany();
|
||||
|
||||
cy.get(commonSelectors.pageLogo).should("be.visible");
|
||||
cy.get(commonSelectors.setUpadminCheckPoint).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.setUpadminCheckPoint
|
||||
);
|
||||
cy.get(commonSelectors.setUpworkspaceCheckPoint).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.setUpworkspaceCheckPoint
|
||||
);
|
||||
cy.get(commonSelectors.companyProfileCheckPoint).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.companyProfileCheckPoint
|
||||
);
|
||||
cy.get(commonSelectors.onboardingPageSubHeader).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.onboardingPageSubHeader
|
||||
);
|
||||
cy.get(commonSelectors.continueButton).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.continueButton
|
||||
);
|
||||
|
||||
signup.commonElementsWorkspaceSetup();
|
||||
cy.get(commonSelectors.onboardingPageHeader).verifyVisibleElement(
|
||||
"have.text",
|
||||
"Enter your phone number"
|
||||
);
|
||||
|
||||
cy.get(".form-control").should("be.visible");
|
||||
cy.get(".tj-onboarding-phone-input-wrapper")
|
||||
.find("input")
|
||||
.type("919876543210");
|
||||
cy.get(commonSelectors.continueButton).click();
|
||||
|
||||
cy.get("body").then(($title) => {
|
||||
if (!$title.text().includes("Enter your phone number")) {
|
||||
cy.get(commonSelectors.workspaceName).verifyVisibleElement(
|
||||
"have.text",
|
||||
"My workspace"
|
||||
);
|
||||
|
||||
logout();
|
||||
cy.appUILogin();
|
||||
|
||||
cy.get(commonSelectors.workspaceName).verifyVisibleElement(
|
||||
"have.text",
|
||||
"My workspace"
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -1,183 +0,0 @@
|
|||
import { commonSelectors } from "Selectors/common";
|
||||
import { commonText } from "Texts/common";
|
||||
import { fake } from "Fixtures/fake";
|
||||
import { addNewUser } from "Support/utils/onboarding";
|
||||
import { logout } from "Support/utils/common";
|
||||
|
||||
describe("Password reset functionality", () => {
|
||||
const data = {};
|
||||
let passwordResetLink = "";
|
||||
|
||||
it("Verify wrong password limit", () => {
|
||||
data.firstName = fake.firstName;
|
||||
data.email = fake.email.toLowerCase();
|
||||
|
||||
cy.defaultWorkspaceLogin();
|
||||
addNewUser(data.firstName, data.email);
|
||||
logout();
|
||||
|
||||
for (let i = 0; i < 5; i++) {
|
||||
cy.clearAndType(commonSelectors.workEmailInputField, data.email);
|
||||
cy.clearAndType(commonSelectors.passwordInputField, "passw");
|
||||
cy.get(commonSelectors.loginButton).click();
|
||||
cy.verifyToastMessage(
|
||||
commonSelectors.toastMessage,
|
||||
"Invalid credentials"
|
||||
);
|
||||
}
|
||||
cy.clearAndType(commonSelectors.workEmailInputField, data.email);
|
||||
cy.clearAndType(commonSelectors.passwordInputField, "passw");
|
||||
cy.get(commonSelectors.loginButton).click();
|
||||
cy.verifyToastMessage(
|
||||
commonSelectors.toastMessage,
|
||||
"Maximum password retry limit reached, please reset your password using forgot password option"
|
||||
);
|
||||
});
|
||||
it("Verify forgot password page elements and functionality", () => {
|
||||
cy.visit("/");
|
||||
cy.get(commonSelectors.forgotPasswordLink).click();
|
||||
cy.get(commonSelectors.pageLogo).should("be.visible");
|
||||
cy.get(commonSelectors.forgotPasswordPageHeader).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.forgotPasswordPageHeader
|
||||
);
|
||||
cy.get(commonSelectors.forgotPasswordPageSubHeader).should(($el) => {
|
||||
expect($el.contents().first().text().trim()).to.eq(
|
||||
"New to"
|
||||
);
|
||||
});
|
||||
cy.get(commonSelectors.createAnAccountLink).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.createAnAccountLink
|
||||
);
|
||||
cy.get(commonSelectors.emailInputLabel).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.emailAddressLabel
|
||||
);
|
||||
cy.get(commonSelectors.emailInputField).should("be.visible");
|
||||
cy.get(commonSelectors.resetPasswordLinkButton)
|
||||
.verifyVisibleElement("have.text", commonText.resetPasswordLinkButton)
|
||||
.and("be.disabled");
|
||||
cy.get(commonSelectors.enterIcon).should("be.visible");
|
||||
|
||||
cy.clearAndType(commonSelectors.emailInputField, data.email);
|
||||
cy.get(commonSelectors.resetPasswordLinkButton).click();
|
||||
|
||||
cy.get("body").then(($title) => {
|
||||
if (!$title.text().includes("Forgot Password")) {
|
||||
cy.verifyToastMessage(
|
||||
commonSelectors.toastMessage,
|
||||
commonText.passwordResetEmailToast
|
||||
);
|
||||
cy.get(commonSelectors.pageLogo).should("be.visible");
|
||||
cy.get(commonSelectors.emailImage).should("be.visible");
|
||||
cy.get(commonSelectors.onboardingPageHeader).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.emailPageHeader
|
||||
);
|
||||
cy.get(commonSelectors.onboardingPageDescription).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.resetPasswordEmailDescription(data.email)
|
||||
);
|
||||
cy.get(commonSelectors.spamMessage).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.spamMessage
|
||||
);
|
||||
cy.get(commonSelectors.onboardingSeperator).should("be.visible");
|
||||
cy.get(commonSelectors.onboardingSeperatorText).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.onboardingSeperatorText
|
||||
);
|
||||
cy.get(commonSelectors.backToLoginButton).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.backToLoginButton
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
cy.task("updateId", {
|
||||
dbconfig: Cypress.env("app_db"),
|
||||
sql: `select forgot_password_token from users where email='${data.email}';`,
|
||||
}).then((resp) => {
|
||||
passwordResetLink = `/reset-password/${resp.rows[0].forgot_password_token}`;
|
||||
});
|
||||
});
|
||||
|
||||
it("Verify reset password page and functionality", () => {
|
||||
cy.visit(passwordResetLink);
|
||||
cy.get(commonSelectors.pageLogo).should("be.visible");
|
||||
cy.get(commonSelectors.passwordResetPageHeader).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.passwordResetPageHeader
|
||||
);
|
||||
cy.get(commonSelectors.newPasswordInputLabel).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.newPasswordInputLabel
|
||||
);
|
||||
cy.get(commonSelectors.newPasswordInputField).should("be.visible");
|
||||
cy.get(commonSelectors.passwordHelperText)
|
||||
.eq(0)
|
||||
.verifyVisibleElement("have.text", commonText.passwordHelperText);
|
||||
cy.get(commonSelectors.confirmPasswordInputFieldLabel).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.confirmPasswordInputFieldLabel
|
||||
);
|
||||
cy.get(commonSelectors.confirmPasswordInputField).should("be.visible");
|
||||
cy.get(commonSelectors.passwordHelperText)
|
||||
.eq(1)
|
||||
.verifyVisibleElement("have.text", commonText.passwordHelperText);
|
||||
cy.get(commonSelectors.resetPasswordButton)
|
||||
.verifyVisibleElement("have.text", commonText.resetPasswordButton)
|
||||
.and("be.disabled");
|
||||
cy.get(commonSelectors.enterIcon).should("be.visible");
|
||||
|
||||
cy.clearAndType(commonSelectors.newPasswordInputField, "Pass");
|
||||
cy.get(commonSelectors.resetPasswordButton).should("be.disabled");
|
||||
|
||||
cy.get(commonSelectors.newPasswordInputField).clear();
|
||||
cy.clearAndType(commonSelectors.confirmPasswordInputField, "Pass");
|
||||
cy.get(commonSelectors.resetPasswordButton).should("be.disabled");
|
||||
|
||||
cy.clearAndType(commonSelectors.newPasswordInputField, "Pass");
|
||||
cy.clearAndType(commonSelectors.confirmPasswordInputField, "Pass");
|
||||
cy.get(commonSelectors.resetPasswordButton).should("be.disabled");
|
||||
|
||||
cy.clearAndType(commonSelectors.newPasswordInputField, "password1");
|
||||
cy.clearAndType(commonSelectors.confirmPasswordInputField, "password");
|
||||
cy.get(commonSelectors.resetPasswordButton).should("be.disabled");
|
||||
|
||||
cy.clearAndType(commonSelectors.newPasswordInputField, "Password");
|
||||
cy.clearAndType(commonSelectors.confirmPasswordInputField, "password");
|
||||
cy.get(commonSelectors.resetPasswordButton).click();
|
||||
cy.verifyToastMessage(commonSelectors.toastMessage, "Password don't match");
|
||||
|
||||
cy.clearAndType(commonSelectors.newPasswordInputField, "Password");
|
||||
cy.clearAndType(commonSelectors.confirmPasswordInputField, "Password");
|
||||
cy.get(commonSelectors.resetPasswordButton).should("be.enabled").click();
|
||||
cy.verifyToastMessage(
|
||||
commonSelectors.toastMessage,
|
||||
commonText.passwordResetSuccessToast
|
||||
);
|
||||
|
||||
cy.get(commonSelectors.pageLogo).should("be.visible");
|
||||
cy.get(commonSelectors.passwordResetPageHeader).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.passwordResetSuccessPageHeader
|
||||
);
|
||||
cy.get(commonSelectors.resetPasswordPageDescription).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.resetPasswordPageDescription
|
||||
);
|
||||
cy.get(commonSelectors.backToLoginButton).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.backToLoginButton
|
||||
);
|
||||
});
|
||||
it("Verify user login using new password", () => {
|
||||
cy.visit("/");
|
||||
cy.clearAndType(commonSelectors.workEmailInputField, data.email);
|
||||
cy.clearAndType(commonSelectors.passwordInputField, "Password");
|
||||
cy.get(commonSelectors.loginButton).click();
|
||||
cy.get(commonSelectors.workspaceName).should("be.visible");
|
||||
});
|
||||
});
|
||||
|
|
@ -1,85 +0,0 @@
|
|||
import { commonSelectors } from "Selectors/common";
|
||||
import { fake } from "Fixtures/fake";
|
||||
import { commonText, path } from "Texts/common";
|
||||
|
||||
describe("Login functionality", () => {
|
||||
let user;
|
||||
const invalidEmail = fake.email;
|
||||
const invalidPassword = fake.password;
|
||||
|
||||
beforeEach(() => {
|
||||
cy.fixture("credentials/login.json").then((login) => {
|
||||
user = login;
|
||||
});
|
||||
cy.visit("/");
|
||||
});
|
||||
it("Should verify elements on the login page", () => {
|
||||
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(commonSelectors.loginButton).click();
|
||||
cy.get(commonSelectors.emailInputError).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.emailInputError
|
||||
);
|
||||
|
||||
cy.clearAndType(commonSelectors.workEmailInputField, invalidEmail);
|
||||
cy.get(commonSelectors.loginButton).click();
|
||||
cy.verifyToastMessage(
|
||||
commonSelectors.toastMessage,
|
||||
commonText.loginErrorToast
|
||||
);
|
||||
|
||||
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(commonSelectors.workEmailInputField, user.email);
|
||||
cy.get(commonSelectors.passwordInputField).clear();
|
||||
cy.get(commonSelectors.loginButton).click();
|
||||
cy.verifyToastMessage(
|
||||
commonSelectors.toastMessage,
|
||||
commonText.loginErrorToast
|
||||
);
|
||||
|
||||
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", () => {
|
||||
cy.login(user.email, user.password);
|
||||
});
|
||||
});
|
||||
|
|
@ -1,104 +0,0 @@
|
|||
import { commonSelectors } from "Selectors/common";
|
||||
import { commonText } from "Texts/common";
|
||||
import { SignUpPageElements } from "Support/utils/onboarding";
|
||||
import { fake } from "Fixtures/fake";
|
||||
import {
|
||||
verifyConfirmEmailPage,
|
||||
verifyConfirmPageElements,
|
||||
verifyOnboardingQuestions,
|
||||
verifyInvalidInvitationLink,
|
||||
updateWorkspaceName
|
||||
} from "Support/utils/onboarding";
|
||||
import { dashboardText } from "Texts/dashboard";
|
||||
import {
|
||||
verifyandModifyUserRole,
|
||||
verifyandModifySizeOftheCompany,
|
||||
} from "Support/utils/selfHostSignUp";
|
||||
|
||||
describe("User signup", () => {
|
||||
const data = {};
|
||||
let invitationLink = "";
|
||||
|
||||
it("Verify the signup flow and UI elements", () => {
|
||||
data.fullName = fake.fullName;
|
||||
data.email = fake.email.toLowerCase().replaceAll("[^A-Za-z]", "");
|
||||
data.workspaceName = fake.companyName;
|
||||
|
||||
cy.visit("/");
|
||||
cy.get(commonSelectors.createAnAccountLink).realClick();
|
||||
SignUpPageElements();
|
||||
|
||||
cy.clearAndType(commonSelectors.nameInputField, data.fullName);
|
||||
cy.clearAndType(commonSelectors.emailInputField, data.email);
|
||||
cy.clearAndType(commonSelectors.passwordInputField, commonText.password);
|
||||
cy.get(commonSelectors.signUpButton).click();
|
||||
cy.wait(500);
|
||||
verifyConfirmEmailPage(data.email);
|
||||
|
||||
cy.task("updateId", {
|
||||
dbconfig: Cypress.env("app_db"),
|
||||
sql: `select invitation_token from users where email='${data.email}';`,
|
||||
}).then((resp) => {
|
||||
invitationLink = `/invitations/${resp.rows[0].invitation_token}`;
|
||||
cy.visit(invitationLink);
|
||||
});
|
||||
|
||||
verifyConfirmPageElements();
|
||||
cy.get(commonSelectors.setUpToolJetButton).click();
|
||||
cy.wait(4000);
|
||||
verifyOnboardingQuestions(data.fullName, data.workspaceName);
|
||||
});
|
||||
it("Verify invalid invitation link", () => {
|
||||
cy.log(invitationLink)
|
||||
cy.visit(invitationLink);
|
||||
verifyInvalidInvitationLink();
|
||||
cy.get(commonSelectors.backtoSignUpButton).click();
|
||||
cy.get(commonSelectors.SignUpSectionHeader).should("be.visible");
|
||||
});
|
||||
it("Verify onboarding flow", () => {
|
||||
data.fullName = fake.fullName;
|
||||
data.email = fake.email.toLowerCase().replaceAll("[^A-Za-z]", "");
|
||||
data.workspaceName = fake.companyName;
|
||||
|
||||
cy.visit("/");
|
||||
cy.get(commonSelectors.createAnAccountLink).realClick();
|
||||
|
||||
cy.clearAndType(commonSelectors.nameInputField, data.fullName);
|
||||
cy.clearAndType(commonSelectors.emailInputField, data.email);
|
||||
cy.clearAndType(commonSelectors.passwordInputField, commonText.password);
|
||||
cy.get(commonSelectors.signUpButton).click();
|
||||
cy.wait(8000);
|
||||
cy.get(commonSelectors.resendEmailButton).click();
|
||||
cy.get(commonSelectors.editEmailButton).click();
|
||||
cy.get(commonSelectors.nameInputField).verifyVisibleElement("have.value", data.fullName)
|
||||
cy.get(commonSelectors.emailInputField).verifyVisibleElement("have.value", data.email);
|
||||
cy.get(commonSelectors.passwordInputField).verifyVisibleElement("have.value", "");
|
||||
|
||||
cy.task("updateId", {
|
||||
dbconfig: Cypress.env("app_db"),
|
||||
sql: `select invitation_token from users where email='${data.email}';`,
|
||||
}).then((resp) => {
|
||||
invitationLink = `/invitations/${resp.rows[0].invitation_token}`;
|
||||
cy.visit(invitationLink);
|
||||
});
|
||||
cy.get(commonSelectors.setUpToolJetButton).click();
|
||||
cy.clearAndType(commonSelectors.companyNameInputField, data.workspaceName);
|
||||
cy.get(commonSelectors.continueButton).focus().type('{enter}');
|
||||
|
||||
cy.get(commonSelectors.backArrow).click()
|
||||
cy.get(commonSelectors.companyNameInputField).verifyVisibleElement("have.value", data.workspaceName);
|
||||
cy.get(commonSelectors.continueButton).focus().type('{enter}');
|
||||
cy.get('[data-cy="head-of-engineering-radio-button"]').check()
|
||||
cy.get(commonSelectors.continueButton).focus().type('{enter}');
|
||||
|
||||
cy.get(commonSelectors.backArrow).click()
|
||||
cy.get('[data-cy="head-of-engineering-radio-button"]').should("be.checked")
|
||||
cy.get(commonSelectors.continueButton).focus().type('{enter}');
|
||||
|
||||
cy.get('[data-cy="1-10-radio-button"]').check()
|
||||
cy.get(commonSelectors.continueButton).focus().type('{enter}');
|
||||
cy.get(commonSelectors.backArrow).click()
|
||||
cy.get('[data-cy="1-10-radio-button"]').should("be.checked")
|
||||
cy.get(commonSelectors.continueButton).focus().type('{enter}');
|
||||
})
|
||||
});
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
import { commonSelectors } from "Selectors/common";
|
||||
import { fake } from "Fixtures/fake";
|
||||
import { commonText, path } from "Texts/common";
|
||||
import { onboardingSelectors } from "Selectors/onboarding";
|
||||
import { dashboardSelector } from "Selectors/dashboard";
|
||||
import { logout } from "Support/utils/common";
|
||||
|
||||
describe("Login functionality", () => {
|
||||
let user;
|
||||
const invalidEmail = fake.email;
|
||||
const invalidPassword = fake.password;
|
||||
|
||||
beforeEach(() => {
|
||||
cy.fixture("credentials/login.json").then((login) => {
|
||||
user = login;
|
||||
});
|
||||
cy.visit("/");
|
||||
});
|
||||
it("Should verify elements on the login page", () => {
|
||||
cy.url().should("include", path.loginPath);
|
||||
cy.get(commonSelectors.pageLogo).should("be.visible");
|
||||
cy.get(commonSelectors.signInHeader).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.signInHeader
|
||||
);
|
||||
cy.get(onboardingSelectors.emailLabel).verifyVisibleElement(
|
||||
"have.text",
|
||||
"Email *"
|
||||
);
|
||||
cy.get(onboardingSelectors.passwordLabel).should(($el) => {
|
||||
expect($el.contents().first().text().trim()).to.eq(
|
||||
commonText.LoginPasswordLabel
|
||||
);
|
||||
});
|
||||
cy.get(commonSelectors.forgotPasswordLink).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.forgotPasswordLink
|
||||
);
|
||||
cy.get(onboardingSelectors.signInButton).verifyVisibleElement(
|
||||
"have.text",
|
||||
"Sign in"
|
||||
);
|
||||
cy.get(onboardingSelectors.signInButton).should("be.disabled");
|
||||
|
||||
cy.get(onboardingSelectors.signupEmailInput).should("be.visible");
|
||||
cy.get(onboardingSelectors.loginPasswordInput).should("be.visible");
|
||||
});
|
||||
|
||||
it("Should be able to login with valid credentials", () => {
|
||||
cy.appUILogin(user.email, user.password);
|
||||
cy.get(commonSelectors.settingsIcon).click();
|
||||
cy.get(dashboardSelector.logoutLink);
|
||||
});
|
||||
|
||||
it("Should not be able to login with invalid credentials", () => {
|
||||
cy.wait(3000);
|
||||
cy.clearAndType(onboardingSelectors.signupEmailInput, "test");
|
||||
cy.clearAndType(onboardingSelectors.signupEmailInput, "test");
|
||||
cy.get(commonSelectors.emailInputError).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.emailInputError
|
||||
);
|
||||
cy.get(onboardingSelectors.signInButton).should("be.disabled");
|
||||
|
||||
cy.get(onboardingSelectors.signupEmailInput).clear();
|
||||
cy.clearAndType(onboardingSelectors.loginPasswordInput, invalidPassword);
|
||||
cy.get(onboardingSelectors.signInButton).should("be.disabled");
|
||||
|
||||
cy.clearAndType(onboardingSelectors.signupEmailInput, user.email);
|
||||
cy.get(onboardingSelectors.loginPasswordInput).clear();
|
||||
cy.get(onboardingSelectors.signInButton).should("be.disabled");
|
||||
|
||||
cy.clearAndType(onboardingSelectors.signupEmailInput, user.email);
|
||||
cy.clearAndType(onboardingSelectors.loginPasswordInput, "Pass");
|
||||
cy.get(onboardingSelectors.passwordError).verifyVisibleElement(
|
||||
"have.text",
|
||||
"Password must be at least 5 characters long"
|
||||
);
|
||||
cy.clearAndType(onboardingSelectors.loginPasswordInput, invalidPassword);
|
||||
cy.get(onboardingSelectors.signInButton).click();
|
||||
cy.verifyToastMessage(commonSelectors.toastMessage, "Invalid credentials");
|
||||
});
|
||||
|
||||
it("Should be able to login with valid credentials using api", () => {
|
||||
cy.appUILogin(user.email, user.password);
|
||||
logout();
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
import { commonSelectors } from "Selectors/common";
|
||||
import { commonText } from "Texts/common";
|
||||
import { SignUpPageElements } from "Support/utils/onboarding";
|
||||
import { fake } from "Fixtures/fake";
|
||||
import {
|
||||
verifyConfirmEmailPage,
|
||||
verifyConfirmPageElements,
|
||||
verifyOnboardingQuestions,
|
||||
verifyInvalidInvitationLink,
|
||||
updateWorkspaceName,
|
||||
} from "Support/utils/onboarding";
|
||||
import { dashboardText } from "Texts/dashboard";
|
||||
import {
|
||||
verifyandModifyUserRole,
|
||||
verifyandModifySizeOftheCompany,
|
||||
} from "Support/utils/selfHostSignUp";
|
||||
import { onboardingSelectors } from "Selectors/onboarding";
|
||||
import { logout } from "Support/utils/common";
|
||||
|
||||
describe("User signup", () => {
|
||||
const data = {};
|
||||
let invitationLink = "";
|
||||
|
||||
it("Verify the signup flow and UI elements", () => {
|
||||
data.fullName = fake.fullName;
|
||||
data.email = fake.email.toLowerCase().replaceAll("[^A-Za-z]", "");
|
||||
data.workspaceName = fake.companyName;
|
||||
|
||||
cy.visit("/");
|
||||
cy.get(commonSelectors.createAnAccountLink).realClick();
|
||||
SignUpPageElements();
|
||||
|
||||
cy.get(onboardingSelectors.nameInput).clear();
|
||||
cy.get(onboardingSelectors.nameInput).type(data.fullName);
|
||||
cy.clearAndType(onboardingSelectors.signupEmailInput, data.email);
|
||||
cy.clearAndType(
|
||||
onboardingSelectors.loginPasswordInput,
|
||||
commonText.password
|
||||
);
|
||||
cy.get(commonSelectors.signUpButton).click();
|
||||
cy.wait(500);
|
||||
verifyConfirmEmailPage(data.email);
|
||||
|
||||
cy.task("updateId", {
|
||||
dbconfig: Cypress.env("app_db"),
|
||||
sql: `select invitation_token from users where email='${data.email}';`,
|
||||
}).then((resp) => {
|
||||
invitationLink = `/invitations/${resp.rows[0].invitation_token}`;
|
||||
cy.visit(invitationLink);
|
||||
});
|
||||
|
||||
logout();
|
||||
});
|
||||
|
||||
it("Verify invalid invitation link", () => {
|
||||
cy.log(invitationLink);
|
||||
cy.visit(invitationLink);
|
||||
verifyInvalidInvitationLink();
|
||||
cy.get(commonSelectors.pageLogo).click();
|
||||
cy.get('[data-cy="sign-in-header"]').should("be.visible");
|
||||
});
|
||||
|
||||
it("Verify onboarding flow", () => {
|
||||
// rewrite for for EE and cloud
|
||||
data.fullName = fake.fullName;
|
||||
data.email = fake.email.toLowerCase().replaceAll("[^A-Za-z]", "");
|
||||
data.workspaceName = fake.companyName;
|
||||
|
||||
cy.visit("/");
|
||||
cy.wait(8000);
|
||||
cy.get(onboardingSelectors.createAnAccountLink).click();
|
||||
cy.wait(6000);
|
||||
cy.get(onboardingSelectors.nameInput).clear();
|
||||
cy.get(onboardingSelectors.nameInput).type(data.fullName);
|
||||
cy.clearAndType(onboardingSelectors.signupEmailInput, data.email);
|
||||
cy.clearAndType(
|
||||
onboardingSelectors.loginPasswordInput,
|
||||
commonText.password
|
||||
);
|
||||
cy.get(commonSelectors.signUpButton).click();
|
||||
cy.wait(8000);
|
||||
cy.get(commonSelectors.resendEmailButton).click();
|
||||
cy.task("updateId", {
|
||||
dbconfig: Cypress.env("app_db"),
|
||||
sql: `select invitation_token from users where email='${data.email}';`,
|
||||
}).then((resp) => {
|
||||
invitationLink = `/invitations/${resp.rows[0].invitation_token}`;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -11,6 +11,21 @@ import {
|
|||
inviteUserWithUserRole,
|
||||
fetchAndVisitInviteLink,
|
||||
} from "Support/utils/manageUsers";
|
||||
import {
|
||||
addNewUser,
|
||||
visitWorkspaceInvitation,
|
||||
newInvite,
|
||||
} from "Support/utils/onboarding";
|
||||
import { commonText } from "Texts/common";
|
||||
import { setSignupStatus, enableSignUp } from "Support/utils/manageSSO";
|
||||
import { ssoSelector } from "Selectors/manageSSO";
|
||||
import {
|
||||
SignUpPageElements,
|
||||
verifyConfirmEmailPage,
|
||||
signUpLink,
|
||||
verifyOnboardingQuestions,
|
||||
} from "Support/utils/onboarding";
|
||||
|
||||
import {
|
||||
navigateToManageUsers,
|
||||
logout,
|
||||
|
|
@ -20,20 +35,20 @@ import {
|
|||
import { updateWorkspaceName } from "Support/utils/userPermissions";
|
||||
import { groupsSelector } from "Selectors/manageGroups";
|
||||
import { groupsText } from "Texts/manageGroups";
|
||||
import { addNewUser, visitWorkspaceInvitation } from "Support/utils/onboarding";
|
||||
import { commonText } from "Texts/common";
|
||||
import { onboardingSelectors } from "Selectors/onboarding";
|
||||
|
||||
let invitationToken,
|
||||
organizationToken,
|
||||
workspaceId,
|
||||
userId,
|
||||
url = "";
|
||||
|
||||
const data = {};
|
||||
|
||||
describe("Manage Users", () => {
|
||||
describe("user invite flow cases", () => {
|
||||
beforeEach(() => {
|
||||
cy.defaultWorkspaceLogin();
|
||||
});
|
||||
let invitationToken,
|
||||
organizationToken,
|
||||
workspaceId,
|
||||
userId,
|
||||
url = "";
|
||||
it("Should verify the Manage users page", () => {
|
||||
data.firstName = fake.firstName;
|
||||
data.email = fake.email.toLowerCase().replaceAll("[^A-Za-z]", "");
|
||||
|
|
@ -45,8 +60,7 @@ describe("Manage Users", () => {
|
|||
cy.get(usersSelector.usersPageTitle).should("be.visible");
|
||||
cy.get(usersSelector.buttonAddUsers).click();
|
||||
|
||||
cy.get(usersSelector.buttonInviteUsers).should('be.disabled');
|
||||
|
||||
cy.get(usersSelector.buttonInviteUsers).should("be.disabled");
|
||||
|
||||
cy.clearAndType(commonSelectors.inputFieldFullName, data.firstName);
|
||||
cy.clearAndType(commonSelectors.inputFieldEmailAddress, data.email);
|
||||
|
|
@ -55,7 +69,7 @@ describe("Manage Users", () => {
|
|||
"have.text",
|
||||
"Email is not valid"
|
||||
);
|
||||
cy.get(usersSelector.buttonInviteUsers).should('be.disabled');
|
||||
cy.get(usersSelector.buttonInviteUsers).should("be.disabled");
|
||||
|
||||
cy.clearAndType(commonSelectors.inputFieldFullName, data.firstName);
|
||||
cy.clearAndType(
|
||||
|
|
@ -64,18 +78,25 @@ describe("Manage Users", () => {
|
|||
);
|
||||
cy.get(usersSelector.buttonInviteUsers).click();
|
||||
|
||||
cy.get('[data-cy="modal-icon"]').should('be.visible')
|
||||
cy.get('[data-cy="modal-header"]').verifyVisibleElement("have.text", "Duplicate email");
|
||||
cy.get(commonSelectors.modalMessage).verifyVisibleElement("have.text", "Duplicate email found. Please provide a unique email address.")
|
||||
cy.get('[data-cy="close-button"]:eq(1)').should('be.visible').click();
|
||||
cy.get(commonSelectors.inputFieldEmailAddress).should("have.value", usersText.adminUserEmail)
|
||||
|
||||
cy.get('[data-cy="modal-icon"]').should("be.visible");
|
||||
cy.get('[data-cy="modal-header"]').verifyVisibleElement(
|
||||
"have.text",
|
||||
"Duplicate email"
|
||||
);
|
||||
cy.get(commonSelectors.modalMessage).verifyVisibleElement(
|
||||
"have.text",
|
||||
"Duplicate email found. Please provide a unique email address."
|
||||
);
|
||||
cy.get('[data-cy="close-button"]:eq(1)').should("be.visible").click();
|
||||
cy.get(commonSelectors.inputFieldEmailAddress).should(
|
||||
"have.value",
|
||||
usersText.adminUserEmail
|
||||
);
|
||||
});
|
||||
|
||||
it("Should verify the confirm invite page and new user account", () => {
|
||||
data.firstName = fake.firstName;
|
||||
data.email = fake.email.toLowerCase().replaceAll("[^A-Za-z]", "");
|
||||
// cy.removeAssignedApps();
|
||||
|
||||
navigateToManageUsers();
|
||||
fillUserInviteForm(data.firstName, data.email);
|
||||
|
|
@ -84,9 +105,9 @@ describe("Manage Users", () => {
|
|||
fetchAndVisitInviteLink(data.email);
|
||||
confirmInviteElements(data.email);
|
||||
|
||||
cy.clearAndType(commonSelectors.passwordInputField, "pass");
|
||||
cy.clearAndType(onboardingSelectors.loginPasswordInput, "pass");
|
||||
cy.get(commonSelectors.signUpButton).should("be.disabled");
|
||||
cy.clearAndType(commonSelectors.passwordInputField, usersText.password);
|
||||
cy.clearAndType(onboardingSelectors.loginPasswordInput, usersText.password);
|
||||
cy.get(commonSelectors.signUpButton).should("not.be.disabled");
|
||||
cy.get(commonSelectors.signUpButton).click();
|
||||
|
||||
|
|
@ -98,14 +119,12 @@ describe("Manage Users", () => {
|
|||
"have.text",
|
||||
commonText.invitePageSubHeader
|
||||
);
|
||||
cy.verifyLabel("Name");
|
||||
cy.get(commonSelectors.invitedUserName).verifyVisibleElement(
|
||||
"have.text",
|
||||
data.firstName
|
||||
);
|
||||
cy.verifyLabel("Email");
|
||||
|
||||
cy.get(commonSelectors.invitedUserEmail).verifyVisibleElement(
|
||||
cy.wait(3000);
|
||||
cy.get(commonSelectors.invitedUseremail).verifyVisibleElement(
|
||||
"have.text",
|
||||
data.email
|
||||
);
|
||||
|
|
@ -155,14 +174,9 @@ describe("Manage Users", () => {
|
|||
|
||||
logout();
|
||||
cy.visit("/");
|
||||
cy.clearAndType(commonSelectors.workEmailInputField, data.email);
|
||||
cy.clearAndType(commonSelectors.passwordInputField, usersText.password);
|
||||
cy.get(commonSelectors.loginButton).click();
|
||||
|
||||
updateWorkspaceName(data.email);
|
||||
cy.get(commonSelectors.workspaceName).click();
|
||||
cy.contains("My workspace").should("not.exist");
|
||||
logout();
|
||||
cy.clearAndType(onboardingSelectors.signupEmailInput, data.email);
|
||||
cy.clearAndType(onboardingSelectors.loginPasswordInput, usersText.password);
|
||||
cy.get(onboardingSelectors.signInButton).click();
|
||||
|
||||
cy.defaultWorkspaceLogin();
|
||||
navigateToManageUsers();
|
||||
|
|
@ -177,9 +191,9 @@ describe("Manage Users", () => {
|
|||
|
||||
visitWorkspaceInvitation(data.email, "My workspace");
|
||||
|
||||
cy.clearAndType(commonSelectors.workEmailInputField, data.email);
|
||||
cy.clearAndType(commonSelectors.passwordInputField, "password");
|
||||
cy.get(commonSelectors.signInButton).click();
|
||||
cy.clearAndType(onboardingSelectors.signupEmailInput, data.email);
|
||||
cy.clearAndType(onboardingSelectors.loginPasswordInput, "password");
|
||||
cy.get(onboardingSelectors.signInButton).click();
|
||||
cy.get(usersSelector.acceptInvite).click();
|
||||
cy.verifyToastMessage(commonSelectors.toastMessage, usersText.inviteToast);
|
||||
logout();
|
||||
|
|
@ -199,7 +213,6 @@ describe("Manage Users", () => {
|
|||
data.groupName1 = fake.firstName.replaceAll("[^A-Za-z]", "");
|
||||
data.groupName2 = fake.firstName.replaceAll("[^A-Za-z]", "");
|
||||
|
||||
|
||||
const groupNames = ["All users", "Admin"];
|
||||
|
||||
navigateToManageUsers();
|
||||
|
|
@ -213,10 +226,6 @@ describe("Manage Users", () => {
|
|||
}
|
||||
});
|
||||
cy.get('[data-cy="user-group-select"]>>>>>').eq(0).type("Test");
|
||||
cy.get(".css-1wlit7h-NoOptionsMessage").verifyVisibleElement(
|
||||
"have.text",
|
||||
"No groups found"
|
||||
);
|
||||
cy.get(commonSelectors.cancelButton).click();
|
||||
|
||||
cy.get(usersSelector.buttonAddUsers).click();
|
||||
|
|
@ -225,7 +234,7 @@ describe("Manage Users", () => {
|
|||
cy.get(commonSelectors.cancelButton).click();
|
||||
|
||||
cy.get(usersSelector.buttonAddUsers).click();
|
||||
cy.get('.selected-value').should('have.text', "End-user")
|
||||
cy.get(".selected-value").should("have.text", "End-user");
|
||||
cy.get(commonSelectors.cancelButton).click();
|
||||
|
||||
inviteUserWithUserRole(data.firstName, data.email, "Admin");
|
||||
|
|
@ -257,7 +266,7 @@ describe("Manage Users", () => {
|
|||
data.groupName2
|
||||
);
|
||||
logout();
|
||||
|
||||
cy.wait(3000);
|
||||
cy.defaultWorkspaceLogin();
|
||||
navigateToManageGroups();
|
||||
cy.get(groupsSelector.groupLink(data.groupName1)).click();
|
||||
|
|
@ -337,12 +346,27 @@ describe("Manage Users", () => {
|
|||
|
||||
cy.get(usersSelector.buttonInviteUsers).click();
|
||||
|
||||
cy.get('[data-cy="modal-title"] > .tj-text-md').verifyVisibleElement("have.text", "Edit user role")
|
||||
cy.get('[data-cy="user-email"]').verifyVisibleElement("have.text", data.email);
|
||||
cy.get('[data-cy="modal-body"]>').verifyVisibleElement("have.text", "Are you sure you want to continue?");
|
||||
cy.get('.modal-footer > [data-cy="cancel-button"]').verifyVisibleElement("have.text", "Cancel");
|
||||
cy.get('[data-cy="confim-button"]').verifyVisibleElement("have.text", "Continue");
|
||||
cy.get('[data-cy="modal-close-button"]').should('be.visible').click();
|
||||
cy.get('[data-cy="modal-title"] > .tj-text-md').verifyVisibleElement(
|
||||
"have.text",
|
||||
"Edit user role"
|
||||
);
|
||||
cy.get('[data-cy="user-email"]').verifyVisibleElement(
|
||||
"have.text",
|
||||
data.email
|
||||
);
|
||||
cy.get('[data-cy="modal-body"]>').verifyVisibleElement(
|
||||
"have.text",
|
||||
"Updating the user's details will change their role from end-user to admin. Are you sure you want to continue?"
|
||||
);
|
||||
cy.get('.modal-footer > [data-cy="cancel-button"]').verifyVisibleElement(
|
||||
"have.text",
|
||||
"Cancel"
|
||||
);
|
||||
cy.get('[data-cy="confim-button"]').verifyVisibleElement(
|
||||
"have.text",
|
||||
"Continue"
|
||||
);
|
||||
cy.get('[data-cy="modal-close-button"]').should("be.visible").click();
|
||||
|
||||
cy.get(usersSelector.userActionButton).click();
|
||||
cy.get(usersSelector.editUserDetailsButton).click();
|
||||
|
|
@ -359,7 +383,7 @@ describe("Manage Users", () => {
|
|||
cy.get('[data-cy="group-check-input"]').eq(0).check();
|
||||
|
||||
cy.get(usersSelector.buttonInviteUsers).click();
|
||||
cy.get('.modal-footer > [data-cy="cancel-button"]').click()
|
||||
cy.get('.modal-footer > [data-cy="cancel-button"]').click();
|
||||
|
||||
cy.get(usersSelector.userActionButton).click();
|
||||
cy.get(usersSelector.editUserDetailsButton).click();
|
||||
|
|
@ -376,7 +400,7 @@ describe("Manage Users", () => {
|
|||
cy.get('[data-cy="group-check-input"]').eq(0).check();
|
||||
|
||||
cy.get(usersSelector.buttonInviteUsers).click();
|
||||
cy.get('[data-cy="confim-button"]').click()
|
||||
cy.get('[data-cy="confim-button"]').click();
|
||||
|
||||
cy.verifyToastMessage(
|
||||
commonSelectors.toastMessage,
|
||||
|
|
@ -384,7 +408,10 @@ describe("Manage Users", () => {
|
|||
);
|
||||
|
||||
searchUser(data.email);
|
||||
cy.get('[data-name="role-header"] [data-cy="group-chip"]').should("have.text", "Admin");
|
||||
cy.get('[data-name="role-header"] [data-cy="group-chip"]').should(
|
||||
"have.text",
|
||||
"Admin"
|
||||
);
|
||||
});
|
||||
|
||||
it("Should verify exisiting user invite flow", () => {
|
||||
|
|
@ -404,10 +431,10 @@ describe("Manage Users", () => {
|
|||
cy.get(usersSelector.buttonInviteUsers).click();
|
||||
cy.wait(2000);
|
||||
visitWorkspaceInvitation(data.email, workspaceName);
|
||||
|
||||
cy.clearAndType(commonSelectors.workEmailInputField, data.email);
|
||||
cy.clearAndType(commonSelectors.passwordInputField, "password");
|
||||
cy.get(commonSelectors.signInButton).click();
|
||||
cy.wait(3000);
|
||||
cy.clearAndType(onboardingSelectors.loginEmailInput, data.email);
|
||||
cy.clearAndType(onboardingSelectors.loginPasswordInput, "password");
|
||||
cy.get(onboardingSelectors.signInButton).click();
|
||||
cy.get(usersSelector.acceptInvite).click();
|
||||
cy.verifyToastMessage(commonSelectors.toastMessage, usersText.inviteToast);
|
||||
logout();
|
||||
|
|
@ -421,4 +448,118 @@ describe("Manage Users", () => {
|
|||
cy.get("td small").should("have.text", usersText.activeStatus);
|
||||
});
|
||||
});
|
||||
|
||||
it("should verify the user signup after invited in a workspace", () => {
|
||||
data.firstName = fake.firstName;
|
||||
data.email = fake.email.toLowerCase().replaceAll("[^A-Za-z]", "");
|
||||
data.signUpName = fake.firstName;
|
||||
data.workspaceName = fake.companyName;
|
||||
|
||||
setSignupStatus(true);
|
||||
navigateToManageUsers();
|
||||
fillUserInviteForm(data.firstName, data.email);
|
||||
cy.get(usersSelector.buttonInviteUsers).click();
|
||||
cy.logoutApi();
|
||||
|
||||
cy.visit("/");
|
||||
cy.get(commonSelectors.createAnAccountLink).click();
|
||||
SignUpPageElements();
|
||||
cy.wait(3000);
|
||||
cy.clearAndType(onboardingSelectors.nameInput, data.signUpName);
|
||||
cy.clearAndType(onboardingSelectors.signupEmailInput, data.email);
|
||||
cy.clearAndType(
|
||||
onboardingSelectors.loginPasswordInput,
|
||||
commonText.password
|
||||
);
|
||||
cy.get(commonSelectors.signUpButton).click();
|
||||
cy.wait(1000);
|
||||
signUpLink(data.email);
|
||||
cy.wait(1000);
|
||||
visitWorkspaceInvitation(data.email, "My workspace");
|
||||
cy.clearAndType(onboardingSelectors.signupEmailInput, data.email);
|
||||
cy.clearAndType(onboardingSelectors.loginPasswordInput, usersText.password);
|
||||
cy.get(onboardingSelectors.signInButton).click();
|
||||
cy.wait(3000);
|
||||
cy.get(commonSelectors.invitedUserName).verifyVisibleElement(
|
||||
"have.text",
|
||||
data.signUpName
|
||||
);
|
||||
cy.get(commonSelectors.acceptInviteButton).click();
|
||||
});
|
||||
|
||||
it("should verify the user signup with same creds after invited in a workspace", () => {
|
||||
data.firstName = fake.firstName;
|
||||
data.email = fake.email.toLowerCase().replaceAll("[^A-Za-z]", "");
|
||||
data.signUpName = fake.firstName;
|
||||
data.workspaceName = fake.companyName;
|
||||
|
||||
setSignupStatus(true);
|
||||
navigateToManageUsers();
|
||||
fillUserInviteForm(data.firstName, data.email);
|
||||
cy.get(usersSelector.buttonInviteUsers).click();
|
||||
logout();
|
||||
|
||||
cy.get(commonSelectors.createAnAccountLink).click();
|
||||
SignUpPageElements();
|
||||
cy.wait(5000);
|
||||
|
||||
cy.clearAndType(onboardingSelectors.nameInput, data.signUpName);
|
||||
cy.clearAndType(onboardingSelectors.signupEmailInput, data.email);
|
||||
cy.clearAndType(
|
||||
onboardingSelectors.loginPasswordInput,
|
||||
commonText.password
|
||||
);
|
||||
cy.get(commonSelectors.signUpButton).click();
|
||||
cy.verifyToastMessage(
|
||||
commonSelectors.toastMessage,
|
||||
"The user is already registered. Please check your inbox for the activation link"
|
||||
);
|
||||
});
|
||||
|
||||
it("should verify exisiting user workspace signup from instance using form", () => {
|
||||
data.firstName = fake.firstName;
|
||||
data.email = fake.email.toLowerCase().replaceAll("[^A-Za-z]", "");
|
||||
data.signUpName = fake.firstName;
|
||||
data.workspaceName = fake.firstName.toLowerCase();
|
||||
|
||||
setSignupStatus(true);
|
||||
navigateToManageUsers();
|
||||
addNewUser(data.firstName, data.email);
|
||||
logout();
|
||||
cy.wait(3000);
|
||||
cy.get(commonSelectors.createAnAccountLink).click();
|
||||
cy.wait(1000);
|
||||
cy.clearAndType(onboardingSelectors.nameInput, data.firstName);
|
||||
cy.clearAndType(onboardingSelectors.signupEmailInput, data.email);
|
||||
cy.clearAndType(
|
||||
onboardingSelectors.loginPasswordInput,
|
||||
commonText.password
|
||||
);
|
||||
cy.get(commonSelectors.signUpButton).click();
|
||||
cy.verifyToastMessage(
|
||||
commonSelectors.toastMessage,
|
||||
"User already exists in the workspace."
|
||||
);
|
||||
cy.apiLogin();
|
||||
cy.apiCreateWorkspace(data.workspaceName, data.workspaceName);
|
||||
cy.visit(`${data.workspaceName}`);
|
||||
cy.wait(3000);
|
||||
setSignupStatus(true, data.workspaceName);
|
||||
logout();
|
||||
|
||||
cy.get(commonSelectors.createAnAccountLink).click();
|
||||
cy.wait(3000);
|
||||
cy.clearAndType(onboardingSelectors.nameInput, data.firstName);
|
||||
cy.clearAndType(onboardingSelectors.signupEmailInput, data.email);
|
||||
cy.clearAndType(
|
||||
onboardingSelectors.loginPasswordInput,
|
||||
commonText.password
|
||||
);
|
||||
cy.get(commonSelectors.signUpButton).click();
|
||||
|
||||
cy.defaultWorkspaceLogin();
|
||||
visitWorkspaceInvitation(data.email, data.workspaceName);
|
||||
cy.verifyToastMessage(commonSelectors.toastMessage, usersText.inviteToast);
|
||||
logout();
|
||||
});
|
||||
});
|
||||
|
|
@ -29,6 +29,7 @@ describe("Bulk user upload", () => {
|
|||
const without_lastName =
|
||||
"cypress/fixtures/bulkUser/without_lastname - Sheet1.csv";
|
||||
const invite_users = "cypress/fixtures/bulkUser/invite_users - Sheet1 .csv";
|
||||
const Validinvite = "cypress/fixtures/bulkUser/10usersupload.csv";
|
||||
|
||||
it("Verfiy bulk user upload invalid files", () => {
|
||||
data.firstName = fake.firstName;
|
||||
|
|
@ -42,80 +43,86 @@ describe("Bulk user upload", () => {
|
|||
|
||||
cy.get(usersSelector.buttonAddUsers).click();
|
||||
cy.get(usersSelector.buttonUploadCsvFile).click();
|
||||
|
||||
bulkUserUpload(
|
||||
without_name,
|
||||
"without_name",
|
||||
"Invalid row(s): [first_name, last_name] in [11] row(s). No users were uploaded."
|
||||
"Missing first_name,last_name,groups information in 10 row(s);. No users were uploaded, please update and try again."
|
||||
);
|
||||
|
||||
bulkUserUpload(
|
||||
without_email,
|
||||
"without_email",
|
||||
"Invalid row(s): [email] in [11] row(s). No users were uploaded."
|
||||
);
|
||||
bulkUserUpload(
|
||||
without_group,
|
||||
"without_group",
|
||||
"Invalid row(s): [groups] in [5] row(s). No users were uploaded."
|
||||
);
|
||||
bulkUserUpload(
|
||||
same_email,
|
||||
"same_email",
|
||||
"Duplicate email found. Please provide a unique email address."
|
||||
);
|
||||
bulkUserUpload(
|
||||
invalid_group_name,
|
||||
"invalid_group_name",
|
||||
"11 groups doesn't exist. No users were uploaded"
|
||||
"Missing email,groups information in 10 row(s);. No users were uploaded, please update and try again."
|
||||
);
|
||||
// bulkUserUpload(
|
||||
// without_group,
|
||||
// "without_group",
|
||||
// "Invalid row(s): [groups] in [5] row(s). No users were uploaded."
|
||||
// );
|
||||
|
||||
//Add automation for modal data-cy="close-button"
|
||||
// bulkUserUpload(
|
||||
// same_email,
|
||||
// "same_email",
|
||||
// "Duplicate email found. Please provide a unique email address."
|
||||
// );
|
||||
|
||||
// bulkUserUpload(
|
||||
// invalid_group_name,
|
||||
// "invalid_group_name",
|
||||
// "11 groups doesn't exist. No users were uploaded"
|
||||
// );
|
||||
bulkUserUpload(
|
||||
empty_first_and_last_name,
|
||||
"empty_first_and_last_name",
|
||||
"Invalid row(s): [first_name, last_name] in [1] row(s). No users were uploaded."
|
||||
"Missing first_name,last_name,groups information in 1 row(s);. No users were uploaded, please update and try again."
|
||||
);
|
||||
bulkUserUpload(
|
||||
limit_exceeded_list,
|
||||
"500_invite_users",
|
||||
"You can only invite 250 users at a time"
|
||||
);
|
||||
|
||||
bulkUserUpload(
|
||||
non_existing_group,
|
||||
"non_existing_group",
|
||||
"1 group doesn't exist. No users were uploaded"
|
||||
);
|
||||
bulkUserUpload(
|
||||
multiple_groups,
|
||||
"multiple_groups",
|
||||
"Conflicting Group Memberships: User cannot be in both the Admin group and other groups simultaneously."
|
||||
"2 groups doesn't exist. No users were uploaded"
|
||||
);
|
||||
|
||||
cy.get(usersSelector.inputFieldBulkUpload).selectFile(without_firstName, {
|
||||
force: true,
|
||||
});
|
||||
cy.get(usersSelector.uploadedFileData).should(
|
||||
"contain",
|
||||
"without_firstname"
|
||||
);
|
||||
cy.get(usersSelector.buttonUploadUsers).click();
|
||||
cy.get(".go2072408551")
|
||||
.should("be.visible")
|
||||
.and("have.text", "5 users are being added");
|
||||
//add more groups and verify
|
||||
|
||||
cy.wait(5000);
|
||||
// bulkUserUpload(
|
||||
// multiple_groups,
|
||||
// "multiple_groups",
|
||||
// "Conflicting Group Memberships: User cannot be in both the Admin group and other groups simultaneously."
|
||||
// );
|
||||
|
||||
cy.get(usersSelector.buttonAddUsers).click();
|
||||
cy.get(usersSelector.buttonUploadCsvFile).click();
|
||||
cy.get(usersSelector.inputFieldBulkUpload).selectFile(without_lastName, {
|
||||
force: true,
|
||||
});
|
||||
cy.get(usersSelector.uploadedFileData).should(
|
||||
"contain",
|
||||
"without_lastname"
|
||||
);
|
||||
cy.get(usersSelector.buttonUploadUsers).click();
|
||||
cy.get(".go2072408551")
|
||||
.should("be.visible")
|
||||
.and("have.text", "5 users are being added");
|
||||
// cy.get(usersSelector.inputFieldBulkUpload).selectFile(without_firstName, {
|
||||
// force: true,
|
||||
// });
|
||||
// cy.get(usersSelector.uploadedFileData).should(
|
||||
// "contain",
|
||||
// "without_firstname"
|
||||
// );
|
||||
// cy.get(usersSelector.buttonUploadUsers).click();
|
||||
// cy.get(".go2072408551")
|
||||
// .should("be.visible")
|
||||
// .and("have.text", "Missing first_name,user_role,groups information in 5 row(s);. No users were uploaded, please update and try again.Missing first_name,user_role,groups information in 5 row(s);. No users were uploaded, please update and try again.");
|
||||
|
||||
// cy.wait(5000);
|
||||
// // cy.get(usersSelector.buttonAddUsers).click();
|
||||
// cy.get(usersSelector.buttonUploadCsvFile).click();
|
||||
// cy.get(usersSelector.inputFieldBulkUpload).selectFile(without_lastName, {
|
||||
// force: true,
|
||||
// });
|
||||
// cy.get(usersSelector.uploadedFileData).should(
|
||||
// "contain",
|
||||
// "without_lastname"
|
||||
// );
|
||||
// cy.get(usersSelector.buttonUploadUsers).click();
|
||||
// cy.get(".go2072408551")
|
||||
// .should("be.visible")
|
||||
// .and("have.text", "Missing last_name,user_role,groups information in 5 row(s);. No users were uploaded, please update and try again.Missing last_name,user_role,groups information in 5 row(s);. No users were uploaded, please update and try again.");
|
||||
});
|
||||
|
||||
it("Verify bulk user upload functionality", () => {
|
||||
|
|
@ -130,22 +137,14 @@ describe("Bulk user upload", () => {
|
|||
cy.get(usersSelector.buttonAddUsers).click();
|
||||
cy.get(usersSelector.buttonUploadCsvFile).click();
|
||||
|
||||
cy.get(usersSelector.inputFieldBulkUpload).selectFile(invite_users, {
|
||||
force: true,
|
||||
});
|
||||
cy.get(usersSelector.uploadedFileData).should("contain", "invite_users");
|
||||
cy.get(commonSelectors.cancelButton).click();
|
||||
|
||||
cy.get(usersSelector.buttonAddUsers).click();
|
||||
cy.get(usersSelector.buttonUploadCsvFile).click();
|
||||
cy.get(usersSelector.inputFieldBulkUpload).selectFile(invite_users, {
|
||||
cy.get(usersSelector.inputFieldBulkUpload).selectFile(Validinvite, {
|
||||
force: true,
|
||||
});
|
||||
cy.get(commonSelectors.fileSelector).should("contain", " 10usersupload");
|
||||
cy.get(usersSelector.buttonUploadUsers).click();
|
||||
cy.wait(30000);
|
||||
cy.get(".go2072408551")
|
||||
.should("be.visible")
|
||||
.and("have.text", "250 users are being added");
|
||||
.and("have.text", "10 users are being added");
|
||||
common.searchUser("test12@gmail.com");
|
||||
cy.contains("td", "test12@gmail.com")
|
||||
.parent()
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
import { commonSelectors } from "Selectors/common";
|
||||
import { commonText } from "Texts/common";
|
||||
import * as signup from "Support/utils/selfHostSignUp";
|
||||
import { logout } from "Support/utils/common";
|
||||
import { onboardingSelectors } from "Selectors/onboarding";
|
||||
|
||||
//selfhostsetup
|
||||
describe("Self host onboarding", () => {
|
||||
beforeEach(() => {
|
||||
cy.visit("/setup");
|
||||
});
|
||||
it("verify elements on self host onboarding page", () => {
|
||||
cy.get(commonSelectors.HostBanner).should("be.visible");
|
||||
cy.get(commonSelectors.pageLogo).should("be.visible");
|
||||
cy.get(commonSelectors.adminSetup).should("be.visible");
|
||||
cy.get(commonSelectors.signupTerms).should("be.visible");
|
||||
|
||||
cy.get(commonSelectors.userNameInputLabel).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.userNameInputLabel
|
||||
);
|
||||
cy.get(commonSelectors.nameInputField).should("be.visible");
|
||||
cy.get(commonSelectors.emailInputLabel).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.emailInputLabel
|
||||
);
|
||||
cy.get(onboardingSelectors.emailInput).should("be.visible");
|
||||
cy.get(commonSelectors.passwordLabel).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.passwordLabel
|
||||
);
|
||||
cy.get(onboardingSelectors.passwordInput).should("be.visible");
|
||||
cy.get(commonSelectors.passwordHelperTextSignup).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.passwordHelperText
|
||||
);
|
||||
|
||||
cy.get(commonSelectors.signUpTermsHelperText).should(($el) => {
|
||||
expect($el.contents().first().text().trim()).to.eq(
|
||||
commonText.selfHostSignUpTermsHelperText
|
||||
);
|
||||
});
|
||||
cy.get(commonSelectors.termsOfServiceLink)
|
||||
.verifyVisibleElement("have.text", commonText.termsOfServiceLink)
|
||||
.and("have.attr", "href")
|
||||
.and("equal", "https://www.tooljet.com/terms");
|
||||
cy.get(commonSelectors.privacyPolicyLink)
|
||||
.verifyVisibleElement("have.text", commonText.privacyPolicyLink)
|
||||
.and("have.attr", "href")
|
||||
.and("equal", "https://www.tooljet.com/privacy");
|
||||
|
||||
cy.clearAndType(commonSelectors.nameInputField, "The Developer");
|
||||
cy.clearAndType(onboardingSelectors.emailInput, "dev@tooljet.io");
|
||||
cy.clearAndType(onboardingSelectors.passwordInput, "password");
|
||||
cy.get(commonSelectors.continueButton).click();
|
||||
|
||||
cy.get(commonSelectors.setUpworkspaceCheckPoint).verifyVisibleElement(
|
||||
"have.text",
|
||||
"Set up your workspace!"
|
||||
);
|
||||
cy.get(commonSelectors.workspaceNameInputLabel).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.workspaceNameInputLabel
|
||||
);
|
||||
cy.get(commonSelectors.workspaceNameInputField).should("be.visible");
|
||||
cy.clearAndType(commonSelectors.workspaceNameInputField, "My workspace");
|
||||
cy.get(commonSelectors.OnbordingContinue).click();
|
||||
|
||||
cy.get(commonSelectors.skipbutton).click();
|
||||
cy.get(commonSelectors.backLogo).click();
|
||||
cy.get(commonSelectors.backtoapps).click();
|
||||
|
||||
logout();
|
||||
cy.appUILogin();
|
||||
|
||||
cy.get(commonSelectors.workspaceName).verifyVisibleElement(
|
||||
"have.text",
|
||||
"My workspace"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,187 @@
|
|||
import { commonSelectors } from "Selectors/common";
|
||||
import { commonText } from "Texts/common";
|
||||
import { fake } from "Fixtures/fake";
|
||||
import { addNewUser } from "Support/utils/onboarding";
|
||||
import { logout } from "Support/utils/common";
|
||||
import { onboardingSelectors } from "Selectors/onboarding";
|
||||
|
||||
|
||||
describe("Password reset functionality", () => {
|
||||
const data = {};
|
||||
let passwordResetLink = "";
|
||||
|
||||
it("Verify wrong password limit", () => {
|
||||
data.firstName = fake.firstName;
|
||||
data.email = fake.email.toLowerCase();
|
||||
|
||||
cy.defaultWorkspaceLogin();
|
||||
addNewUser(data.firstName, data.email);
|
||||
logout();
|
||||
|
||||
for (let i = 0; i < 5; i++) {
|
||||
cy.clearAndType(onboardingSelectors.signupEmailInput, data.email);
|
||||
cy.clearAndType(onboardingSelectors.loginPasswordInput, "passw");
|
||||
cy.get(onboardingSelectors.signInButton).click();
|
||||
cy.verifyToastMessage(
|
||||
commonSelectors.toastMessage,
|
||||
"Invalid credentials"
|
||||
);
|
||||
}
|
||||
cy.clearAndType(onboardingSelectors.signupEmailInput, data.email);
|
||||
cy.clearAndType(onboardingSelectors.loginPasswordInput, "passw");
|
||||
cy.get(onboardingSelectors.signInButton).click();
|
||||
cy.verifyToastMessage(
|
||||
commonSelectors.toastMessage,
|
||||
"Maximum password retry limit reached, please reset your password using forgot password option"
|
||||
);
|
||||
});
|
||||
|
||||
it("Verify forgot password page elements and functionality", () => {
|
||||
cy.visit("/");
|
||||
cy.get(commonSelectors.forgotPasswordLink).click();
|
||||
cy.get(commonSelectors.pageLogo).should("be.visible");
|
||||
cy.get(commonSelectors.forgotPasswordPageHeader).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.forgotPasswordPageHeader
|
||||
);
|
||||
cy.get(commonSelectors.forgotPasswordPageSubHeader).verifyVisibleElement(
|
||||
"have.text",
|
||||
"New to ToolJet? Create an account"
|
||||
);
|
||||
|
||||
cy.get(commonSelectors.createAnAccountLink).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.createAnAccountLink
|
||||
);
|
||||
|
||||
cy.get('[data-cy="email-input-field-label"]').verifyVisibleElement(
|
||||
"have.text",
|
||||
"Email address *"
|
||||
);
|
||||
|
||||
cy.get('[data-cy="email-input-field-input"]').should("be.visible");
|
||||
cy.get(commonSelectors.resetPasswordLinkButton)
|
||||
.verifyVisibleElement("have.text", commonText.resetPasswordLinkButton)
|
||||
.and("be.disabled");
|
||||
cy.wait(5000);
|
||||
cy.clearAndType('[data-cy="email-input-field-input"]', data.email);
|
||||
cy.get(commonSelectors.resetPasswordLinkButton).click();
|
||||
|
||||
cy.verifyToastMessage(
|
||||
commonSelectors.toastMessage,
|
||||
commonText.passwordResetEmailToast
|
||||
);
|
||||
cy.get(commonSelectors.pageLogo).should("be.visible");
|
||||
|
||||
cy.get('[data-cy="check-your-mail-header"]').verifyVisibleElement(
|
||||
"have.text",
|
||||
"Check your mail"
|
||||
);
|
||||
|
||||
cy.get(commonSelectors.onboardingPageDescription).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.resetPasswordEmailDescription(data.email)
|
||||
);
|
||||
cy.get(commonSelectors.spamMessage).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.spamMessage
|
||||
);
|
||||
cy.get(commonSelectors.onboardingSeperator).should("be.visible");
|
||||
cy.get(commonSelectors.onboardingSeperatorText).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.onboardingSeperatorText
|
||||
);
|
||||
cy.get(commonSelectors.backToLoginButton).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.backToLoginButton
|
||||
);
|
||||
|
||||
cy.task("updateId", {
|
||||
dbconfig: Cypress.env("app_db"),
|
||||
sql: `select forgot_password_token from users where email='${data.email}';`,
|
||||
}).then((resp) => {
|
||||
passwordResetLink = `/reset-password/${resp.rows[0].forgot_password_token}`;
|
||||
});
|
||||
});
|
||||
|
||||
it("Verify reset password page and functionality", () => {
|
||||
cy.visit(passwordResetLink);
|
||||
cy.get(commonSelectors.pageLogo).should("be.visible");
|
||||
cy.get(commonSelectors.passwordResetPageHeader).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.passwordResetPageHeader
|
||||
);
|
||||
cy.get(commonSelectors.newPasswordInputLabel).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.newPasswordInputLabel
|
||||
);
|
||||
cy.get(commonSelectors.newPasswordInputField).should("be.visible");
|
||||
cy.get(commonSelectors.passwordHelperText)
|
||||
.eq(0)
|
||||
.verifyVisibleElement("have.text", commonText.passwordHelperText);
|
||||
cy.get(commonSelectors.confirmPasswordInputFieldLabel).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.confirmPasswordInputFieldLabel
|
||||
);
|
||||
cy.get(commonSelectors.confirmPasswordInputField).should("be.visible");
|
||||
cy.get(commonSelectors.passwordHelperText).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.passwordHelperText
|
||||
);
|
||||
cy.get(commonSelectors.resetPasswordButton)
|
||||
.verifyVisibleElement("have.text", commonText.resetPasswordButton)
|
||||
.and("be.disabled");
|
||||
|
||||
cy.clearAndType(commonSelectors.newPasswordInputField, "Pass");
|
||||
cy.get(commonSelectors.resetPasswordButton).should("be.disabled");
|
||||
|
||||
cy.get(commonSelectors.newPasswordInputField).clear();
|
||||
cy.clearAndType(commonSelectors.confirmPasswordInputField, "Pass");
|
||||
cy.get(commonSelectors.resetPasswordButton).should("be.disabled");
|
||||
|
||||
cy.clearAndType(commonSelectors.newPasswordInputField, "Pass");
|
||||
cy.clearAndType(commonSelectors.confirmPasswordInputField, "Pass");
|
||||
cy.get(commonSelectors.resetPasswordButton).should("be.disabled");
|
||||
|
||||
cy.clearAndType(commonSelectors.newPasswordInputField, "password1");
|
||||
cy.clearAndType(commonSelectors.confirmPasswordInputField, "password");
|
||||
cy.get(commonSelectors.resetPasswordButton).should("be.disabled");
|
||||
|
||||
cy.clearAndType(commonSelectors.newPasswordInputField, "Password");
|
||||
cy.clearAndType(commonSelectors.confirmPasswordInputField, "password");
|
||||
cy.get('[data-cy="confirm-password-input-error"]').verifyVisibleElement(
|
||||
"have.text",
|
||||
"Passwords don't match"
|
||||
);
|
||||
|
||||
cy.clearAndType(commonSelectors.newPasswordInputField, "Password");
|
||||
cy.clearAndType(commonSelectors.confirmPasswordInputField, "Password");
|
||||
cy.get(commonSelectors.resetPasswordButton).should("be.enabled").click();
|
||||
cy.verifyToastMessage(
|
||||
commonSelectors.toastMessage,
|
||||
commonText.passwordResetSuccessToast
|
||||
);
|
||||
|
||||
cy.get(commonSelectors.pageLogo).should("be.visible");
|
||||
cy.get('[data-cy="password-has-been-reset-header"]').verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.passwordResetSuccessPageHeader
|
||||
);
|
||||
cy.get(commonSelectors.resetPasswordPageDescription).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.resetPasswordPageDescription
|
||||
);
|
||||
cy.get(commonSelectors.backToLoginButton).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.backToLoginButton
|
||||
);
|
||||
});
|
||||
|
||||
it("Verify user login using new password", () => {
|
||||
cy.visit("/");
|
||||
cy.clearAndType(onboardingSelectors.signupEmailInput, data.email);
|
||||
cy.clearAndType(onboardingSelectors.loginPasswordInput, "Password");
|
||||
cy.get(onboardingSelectors.signInButton).click();
|
||||
cy.get(commonSelectors.workspaceName).should("be.visible");
|
||||
});
|
||||
});
|
||||
|
|
@ -31,6 +31,7 @@ describe("dashboard", () => {
|
|||
data.cloneAppName = `cloned-${data.appName}`;
|
||||
data.updatedFolderName = `new-${data.folderName}`;
|
||||
|
||||
|
||||
beforeEach(() => {
|
||||
cy.intercept("GET", "/api/library_apps").as("appLibrary");
|
||||
cy.intercept("DELETE", "/api/folders/*").as("folderDeleted");
|
||||
|
|
@ -59,7 +60,7 @@ describe("dashboard", () => {
|
|||
"My workspace"
|
||||
);
|
||||
cy.get(commonSelectors.workspaceName).click();
|
||||
cy.get(commonSelectors.editRectangleIcon).should("be.visible");
|
||||
// cy.get(commonSelectors.editRectangleIcon).should("be.visible");
|
||||
cy.get(commonSelectors.appCreateButton).verifyVisibleElement(
|
||||
"have.text",
|
||||
"Create an app"
|
||||
|
|
@ -173,10 +174,14 @@ describe("dashboard", () => {
|
|||
});
|
||||
|
||||
it("Should verify app card elements and app card operations", () => {
|
||||
const customLayout = {
|
||||
desktop: { top: 100, left: 20 },
|
||||
mobile: { width: 8, height: 50 },
|
||||
};
|
||||
cy.apiLogin();
|
||||
cy.apiCreateApp(data.appName);
|
||||
cy.openApp();
|
||||
cy.dragAndDropWidget("Table", 250, 250);
|
||||
cy.addComponentToApp(data.appName, "text1", customLayout)
|
||||
|
||||
cy.backToApps();
|
||||
|
||||
|
|
@ -190,11 +195,8 @@ describe("dashboard", () => {
|
|||
data.appName
|
||||
);
|
||||
cy.get(commonSelectors.appCreationDetails).should("be.visible");
|
||||
cy.get(commonSelectors.appCreationDetails)
|
||||
.should("be.visible")
|
||||
.and(($el) => {
|
||||
expect($el.contents().last().text().trim()).to.eq("The Developer");
|
||||
});
|
||||
|
||||
//Add the edited details
|
||||
});
|
||||
|
||||
viewAppCardOptions(data.appName);
|
||||
|
|
@ -287,7 +289,7 @@ describe("dashboard", () => {
|
|||
.and("have.text", dashboardText.appClonedToast);
|
||||
cy.wait(3000);
|
||||
cy.renameApp(data.cloneAppName);
|
||||
cy.dragAndDropWidget("button", 25, 25);
|
||||
cy.addComponentToApp(data.cloneAppName, "button", 25, 25);
|
||||
cy.backToApps();
|
||||
cy.wait("@appLibrary");
|
||||
cy.wait(1000);
|
||||
|
|
@ -339,11 +341,17 @@ describe("dashboard", () => {
|
|||
});
|
||||
|
||||
it("Should verify the app CRUD operation", () => {
|
||||
|
||||
const customLayout = {
|
||||
desktop: { top: 100, left: 20 },
|
||||
mobile: { width: 8, height: 50 },
|
||||
};
|
||||
|
||||
cy.skipWalkthrough();
|
||||
data.appName = `${fake.companyName}-App`;
|
||||
cy.defaultWorkspaceLogin();
|
||||
cy.createApp(data.appName);
|
||||
cy.dragAndDropWidget("Button", 450, 450);
|
||||
cy.addComponentToApp(data.appName, "text1", customLayout)
|
||||
|
||||
cy.backToApps();
|
||||
|
||||
|
|
@ -353,7 +361,8 @@ describe("dashboard", () => {
|
|||
);
|
||||
|
||||
navigateToAppEditor(data.appName);
|
||||
cy.get(commonSelectors.canvas).should("contain", "Button");
|
||||
// cy.get(commonSelectors.canvas).should("contain", "text1");
|
||||
cy.get('.text-widget-section > div').should('be.visible')
|
||||
cy.backToApps();
|
||||
cy.wait("@appLibrary");
|
||||
|
||||
|
|
@ -366,10 +375,16 @@ describe("dashboard", () => {
|
|||
});
|
||||
|
||||
it("Should verify the folder CRUD operation", () => {
|
||||
const customLayout = {
|
||||
desktop: { top: 100, left: 20 },
|
||||
mobile: { width: 8, height: 50 },
|
||||
};
|
||||
|
||||
data.appName = `${fake.companyName}-App`;
|
||||
cy.defaultWorkspaceLogin();
|
||||
cy.createApp(data.appName);
|
||||
cy.dragAndDropWidget("Button", 100, 100);
|
||||
|
||||
cy.addComponentToApp(data.appName, "text1", customLayout)
|
||||
|
||||
cy.backToApps();
|
||||
|
||||
|
|
|
|||
|
|
@ -36,13 +36,12 @@ describe("Redirection error pages", () => {
|
|||
cy.get(commonSelectors.backToHomeButton).click();
|
||||
cy.get(commonSelectors.pageSectionHeader).should("be.visible");
|
||||
cy.logoutApi();
|
||||
|
||||
cy.visit(`/applications/${data.lastName}`);
|
||||
cy.get(commonSelectors.backToHomeButton).click();
|
||||
cy.get(commonSelectors.workEmailLabel).should("be.visible");
|
||||
cy.wait(3000);
|
||||
|
||||
cy.apiLogin("test@tooljet.com", "password");
|
||||
cy.visit(`/applications/${data.lastName}`);
|
||||
cy.get(commonSelectors.backToHomeButton).click();
|
||||
|
||||
});
|
||||
|
||||
it("Verify error message in case of restricted access", () => {
|
||||
|
|
@ -52,22 +51,22 @@ describe("Redirection error pages", () => {
|
|||
cy.openApp();
|
||||
cy.wait(1000);
|
||||
releaseApp();
|
||||
|
||||
cy.get(commonWidgetSelector.shareAppButton).click();
|
||||
cy.clearAndType(commonWidgetSelector.appNameSlugInput, data.slug);
|
||||
cy.pause();
|
||||
cy.wait(1000);
|
||||
cy.logoutApi();
|
||||
|
||||
cy.apiLogin("test@tooljet.com", "password");
|
||||
cy.visit(`/applications/${data.slug}`);
|
||||
|
||||
cy.pause();
|
||||
cy.get(commonSelectors.modalHeader).verifyVisibleElement(
|
||||
"have.text",
|
||||
"Restricted access"
|
||||
"App URL Unavailable"
|
||||
);
|
||||
cy.get(commonSelectors.modalDescription).verifyVisibleElement(
|
||||
"have.text",
|
||||
"You don’t have access to this app. Kindly contact admin to know more."
|
||||
"The app URL is currently unavailable because the app has not been released. Please either release it or contact admin for access."
|
||||
);
|
||||
cy.get(commonSelectors.backToHomeButton).verifyVisibleElement(
|
||||
"have.text",
|
||||
|
|
@ -79,7 +78,7 @@ describe("Redirection error pages", () => {
|
|||
cy.get(commonSelectors.pageSectionHeader).should("be.visible");
|
||||
});
|
||||
|
||||
it.only("Verify error modal for app url of unreleased apps", () => {
|
||||
it.skip("Verify error modal for app url of unreleased apps", () => {
|
||||
data.appName = `${fake.companyName} App`;
|
||||
data.slug = data.appName.toLowerCase().replace(/\s+/g, "-");
|
||||
|
||||
|
|
@ -111,7 +110,7 @@ describe("Redirection error pages", () => {
|
|||
|
||||
cy.url().should(
|
||||
"eq",
|
||||
`http://localhost:8082/error/url-unavailable?appSlug=${data.slug}`
|
||||
`http://localhost:8082/error/restricted`
|
||||
);
|
||||
cy.get(commonSelectors.backToHomeButton).click();
|
||||
cy.get(commonSelectors.pageSectionHeader).should("be.visible");
|
||||
|
|
@ -123,11 +122,11 @@ describe("Redirection error pages", () => {
|
|||
cy.visit(`http://localhost:8082/applications/${data.slug}`);
|
||||
cy.get(commonSelectors.modalHeader).verifyVisibleElement(
|
||||
"have.text",
|
||||
"Restricted access"
|
||||
"App URL Unavailable"
|
||||
);
|
||||
cy.get(commonSelectors.modalDescription).verifyVisibleElement(
|
||||
"have.text",
|
||||
"You don’t have access to this app. Kindly contact admin to know more."
|
||||
"The app URL is currently unavailable because the app has not been released. Please either release it or contact admin for access."
|
||||
);
|
||||
// cy.get('[data-cy="open-app-button"]').verifyVisibleElement("have.text", "Open app")
|
||||
|
||||
|
|
@ -174,7 +173,7 @@ describe("Redirection error pages", () => {
|
|||
);
|
||||
cy.url().should(
|
||||
"eq",
|
||||
`http://localhost:8082/error/url-unavailable?appSlug=${data.slug}`
|
||||
`http://localhost:8082/error/restricted`
|
||||
);
|
||||
cy.get(commonSelectors.backToHomeButton).click();
|
||||
cy.get(commonSelectors.pageSectionHeader).should("be.visible");
|
||||
|
|
|
|||
|
|
@ -1,149 +0,0 @@
|
|||
import { commonSelectors } from "Selectors/common";
|
||||
import { fake } from "Fixtures/fake";
|
||||
import { usersText } from "Texts/manageUsers";
|
||||
import { usersSelector } from "Selectors/manageUsers";
|
||||
import {
|
||||
manageUsersElements,
|
||||
fillUserInviteForm,
|
||||
confirmInviteElements,
|
||||
selectUserGroup,
|
||||
inviteUserWithUserGroups,
|
||||
fetchAndVisitInviteLink,
|
||||
} from "Support/utils/manageUsers";
|
||||
import {
|
||||
navigateToManageUsers,
|
||||
logout,
|
||||
searchUser,
|
||||
navigateToManageGroups,
|
||||
} from "Support/utils/common";
|
||||
import { updateWorkspaceName } from "Support/utils/userPermissions";
|
||||
import { groupsSelector } from "Selectors/manageGroups";
|
||||
import { groupsText } from "Texts/manageGroups";
|
||||
import { addNewUser, visitWorkspaceInvitation, newInvite } from "Support/utils/onboarding";
|
||||
import { commonText } from "Texts/common";
|
||||
import { setSignupStatus, enableSignUp } from "Support/utils/manageSSO";
|
||||
import { ssoSelector } from "Selectors/manageSSO";
|
||||
import {
|
||||
SignUpPageElements,
|
||||
verifyConfirmEmailPage,
|
||||
signUpLink,
|
||||
verifyOnboardingQuestions,
|
||||
} from "Support/utils/onboarding";
|
||||
|
||||
const data = {};
|
||||
|
||||
describe("user invite flow cases", () => {
|
||||
beforeEach(() => {
|
||||
cy.defaultWorkspaceLogin();
|
||||
});
|
||||
it("should verify the user signup after invited in a workspace", () => {
|
||||
data.firstName = fake.firstName;
|
||||
data.email = fake.email.toLowerCase().replaceAll("[^A-Za-z]", "");
|
||||
data.signUpName = fake.firstName;
|
||||
data.workspaceName = fake.companyName;
|
||||
|
||||
setSignupStatus(true);
|
||||
navigateToManageUsers();
|
||||
fillUserInviteForm(data.firstName, data.email);
|
||||
cy.get(usersSelector.buttonInviteUsers).click();
|
||||
cy.logoutApi();
|
||||
|
||||
cy.visit("/");
|
||||
cy.get(commonSelectors.createAnAccountLink).click();
|
||||
SignUpPageElements();
|
||||
|
||||
cy.clearAndType(commonSelectors.nameInputField, data.signUpName);
|
||||
cy.clearAndType(commonSelectors.emailInputField, data.email);
|
||||
cy.clearAndType(commonSelectors.passwordInputField, commonText.password);
|
||||
cy.get(commonSelectors.signUpButton).click();
|
||||
signUpLink(data.email);
|
||||
cy.get(commonSelectors.setUpToolJetButton).click();
|
||||
verifyOnboardingQuestions(data.signUpName, data.workspaceName);
|
||||
visitWorkspaceInvitation(data.email, "My workspace");
|
||||
cy.clearAndType(commonSelectors.workEmailInputField, data.email);
|
||||
cy.clearAndType(commonSelectors.passwordInputField, usersText.password);
|
||||
cy.get(commonSelectors.loginButton).click();
|
||||
|
||||
cy.get(commonSelectors.invitedUserName).verifyVisibleElement(
|
||||
"have.text",
|
||||
data.signUpName
|
||||
);
|
||||
cy.get(commonSelectors.acceptInviteButton).click();
|
||||
});
|
||||
|
||||
it("should verify the user signup after invited in a workspace", () => {
|
||||
data.firstName = fake.firstName;
|
||||
data.email = fake.email.toLowerCase().replaceAll("[^A-Za-z]", "");
|
||||
data.signUpName = fake.firstName;
|
||||
data.workspaceName = fake.companyName;
|
||||
|
||||
setSignupStatus(true);
|
||||
navigateToManageUsers();
|
||||
fillUserInviteForm(data.firstName, data.email);
|
||||
cy.get(usersSelector.buttonInviteUsers).click();
|
||||
logout();
|
||||
|
||||
cy.get(ssoSelector.workspaceSubHeader).verifyVisibleElement(
|
||||
"have.text",
|
||||
"Sign in to your workspace - My workspace"
|
||||
);
|
||||
cy.get(commonSelectors.signInSubHeader).verifyVisibleElement(
|
||||
"have.text",
|
||||
"New to this workspace?Sign up"
|
||||
);
|
||||
cy.get(commonSelectors.createAnAccountLink).click();
|
||||
SignUpPageElements();
|
||||
cy.get(ssoSelector.workspaceSignUpHeader).verifyVisibleElement(
|
||||
"have.text",
|
||||
"Sign up to the workspace - My workspace"
|
||||
);
|
||||
|
||||
cy.clearAndType(commonSelectors.nameInputField, data.signUpName);
|
||||
cy.clearAndType(commonSelectors.emailInputField, data.email);
|
||||
cy.clearAndType(commonSelectors.passwordInputField, commonText.password);
|
||||
cy.get(commonSelectors.signUpButton).click();
|
||||
cy.verifyToastMessage(
|
||||
commonSelectors.toastMessage,
|
||||
"The user is already registered. Please check your inbox for the activation link"
|
||||
);
|
||||
});
|
||||
|
||||
it("should verify exisiting user workspace signup", () => {
|
||||
data.firstName = fake.firstName;
|
||||
data.email = fake.email.toLowerCase().replaceAll("[^A-Za-z]", "");
|
||||
data.signUpName = fake.firstName;
|
||||
data.workspaceName = fake.firstName.toLowerCase();
|
||||
|
||||
setSignupStatus(true);
|
||||
navigateToManageUsers();
|
||||
addNewUser(data.firstName, data.email);
|
||||
logout();
|
||||
|
||||
cy.get(commonSelectors.createAnAccountLink).click();
|
||||
cy.clearAndType(commonSelectors.nameInputField, data.firstName);
|
||||
cy.clearAndType(commonSelectors.emailInputField, data.email);
|
||||
cy.clearAndType(commonSelectors.passwordInputField, commonText.password);
|
||||
cy.get(commonSelectors.signUpButton).click();
|
||||
cy.verifyToastMessage(
|
||||
commonSelectors.toastMessage,
|
||||
"User already exists in the workspace."
|
||||
);
|
||||
cy.apiLogin();
|
||||
cy.apiCreateWorkspace(data.workspaceName, data.workspaceName);
|
||||
cy.visit(`${data.workspaceName}`);
|
||||
cy.wait(3000)
|
||||
setSignupStatus(true, data.workspaceName);
|
||||
logout();
|
||||
|
||||
cy.get(commonSelectors.createAnAccountLink).click();
|
||||
cy.clearAndType(commonSelectors.nameInputField, data.firstName);
|
||||
cy.clearAndType(commonSelectors.emailInputField, data.email);
|
||||
cy.clearAndType(commonSelectors.passwordInputField, commonText.password);
|
||||
cy.get(commonSelectors.signUpButton).click();
|
||||
|
||||
cy.defaultWorkspaceLogin();
|
||||
visitWorkspaceInvitation(data.email, data.workspaceName);
|
||||
cy.verifyToastMessage(commonSelectors.toastMessage, usersText.inviteToast);
|
||||
logout();
|
||||
});
|
||||
});
|
||||
|
|
@ -5,6 +5,7 @@ import { profileText } from "Texts/profile";
|
|||
import { commonSelectors } from "Selectors/common";
|
||||
import { fake } from "Fixtures/fake";
|
||||
import { commonText } from "Texts/common";
|
||||
import { onboardingSelectors } from "Selectors/onboarding";
|
||||
|
||||
describe("Profile Settings", () => {
|
||||
const randomFirstName = fake.firstName;
|
||||
|
|
@ -15,6 +16,7 @@ describe("Profile Settings", () => {
|
|||
common.navigateToProfile();
|
||||
});
|
||||
|
||||
// neeed to reset and seed bd after 1 run (as password changes will get 401 error )
|
||||
it("Should verify the elements on profile settings page and name reset functionality", () => {
|
||||
profile.profilePageElements();
|
||||
|
||||
|
|
@ -183,20 +185,16 @@ describe("Profile Settings", () => {
|
|||
);
|
||||
|
||||
common.logout();
|
||||
|
||||
cy.clearAndType(commonSelectors.workEmailInputField, commonText.email);
|
||||
cy.clearAndType(commonSelectors.passwordInputField, commonText.password);
|
||||
cy.get(commonSelectors.loginButton).click();
|
||||
cy.clearAndType(onboardingSelectors.loginEmailInput, commonText.email);
|
||||
cy.clearAndType(onboardingSelectors.loginPasswordInput, commonText.password);
|
||||
cy.get(onboardingSelectors.signInButton).click();
|
||||
cy.verifyToastMessage(
|
||||
commonSelectors.toastMessage,
|
||||
profileText.loginErrorToast
|
||||
);
|
||||
|
||||
cy.clearAndType(
|
||||
commonSelectors.passwordInputField,
|
||||
profileText.newPassword
|
||||
);
|
||||
cy.get(commonSelectors.signInButton).click();
|
||||
cy.clearAndType(onboardingSelectors.loginPasswordInput, profileText.newPassword);
|
||||
cy.get(onboardingSelectors.signInButton).click();
|
||||
common.navigateToProfile();
|
||||
|
||||
cy.clearAndType(
|
||||
|
|
@ -213,7 +211,7 @@ describe("Profile Settings", () => {
|
|||
|
||||
common.logout();
|
||||
|
||||
cy.login(commonText.email, profileText.password);
|
||||
cy.appUILogin(commonText.email, profileText.password);
|
||||
common.logout();
|
||||
});
|
||||
});
|
||||
|
|
|
|||
11
cypress-tests/cypress/fixtures/bulkUser/10usersupload.csv
Normal file
11
cypress-tests/cypress/fixtures/bulkUser/10usersupload.csv
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
First Name,Last Name,Email,User Role,Group
|
||||
test1,user,test1@gmail.com,Builder,
|
||||
test2,user,test3@gmail.com,End User,
|
||||
Test3,Example,test12@gmail.com,Admin,
|
||||
Test4,Example,test23@gmail.com,End User,
|
||||
Test5,Example,test24@gmail.com,End User,
|
||||
Test6,Example,test25@gmail.com,End User,
|
||||
Test7,Example,test26@gmail.com,Admin,
|
||||
Test8,Example,test27@gmail.com,Builder,
|
||||
Test9,Example,test28@gmail.com,Builder,
|
||||
Test10,Example,test29@gmail.com,End User,
|
||||
|
|
|
@ -1,499 +1,252 @@
|
|||
First Name,Last Name,Email,Groups
|
||||
Vijay,Yadav,vjyaav12@gmail.com,All Users|Admin
|
||||
Vijay,Yadav,vjyaav13@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav14@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav15@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav16@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav17@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav18@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav19@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav20@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav21@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav22@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav23@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav24@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav25@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav26@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav27@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav28@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav29@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav30@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav31@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav32@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav33@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav34@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav35@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav36@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav37@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav38@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav39@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav40@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav41@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav42@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav43@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav44@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav45@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav46@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav47@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav48@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav49@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav50@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav51@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav52@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav53@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav54@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav55@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav56@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav57@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav58@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav59@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav60@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav61@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav62@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav63@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav64@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav65@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav66@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav67@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav68@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav69@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav70@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav71@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav72@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav73@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav74@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav75@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav76@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav77@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav78@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav79@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav80@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav81@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav82@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav83@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav84@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav85@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav86@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav87@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav88@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav89@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav90@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav91@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav92@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav93@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav94@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav95@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav96@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav97@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav98@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav99@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav100@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav101@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav102@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav103@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav104@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav105@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav106@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav107@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav108@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav109@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav110@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav111@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav112@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav113@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav114@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav115@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav116@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav117@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav118@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav119@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav120@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav121@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav122@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav123@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav124@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav125@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav126@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav127@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav128@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav129@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav130@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav131@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav132@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav133@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav134@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav135@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav136@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav137@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav138@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav139@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav140@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav141@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav142@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav143@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav144@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav145@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav146@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav147@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav148@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav149@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav150@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav151@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav152@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav153@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav154@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav155@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav156@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav157@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav158@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav159@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav160@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav161@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav162@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav163@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav164@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav165@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav166@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav167@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav168@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav169@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav170@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav171@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav172@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav173@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav174@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav175@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav176@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav177@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav178@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav179@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav180@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav181@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav182@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav183@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav184@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav185@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav186@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav187@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav188@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav189@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav190@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav191@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav192@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav193@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav194@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav195@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav196@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav197@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav198@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav199@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav200@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav201@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav202@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav203@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav204@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav205@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav206@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav207@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav208@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav209@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav210@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav211@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav212@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav213@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav214@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav215@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav216@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav217@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav218@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav219@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav220@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav221@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav222@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav223@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav224@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav225@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav226@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav227@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav228@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav229@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav230@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav231@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav232@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav233@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav234@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav235@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav236@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav237@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav238@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav239@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav240@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav241@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav242@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav243@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav244@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav245@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav246@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav247@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav248@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav249@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav250@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav251@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav252@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav253@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav254@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav255@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav256@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav257@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav258@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav259@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav260@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav261@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav262@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav263@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav264@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav265@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav266@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav267@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav268@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav269@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav270@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav271@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav272@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav273@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav274@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav275@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav276@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav277@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav278@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav279@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav280@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav281@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav282@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav283@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav284@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav285@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav286@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav287@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav288@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav289@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav290@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav291@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav292@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav293@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav294@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav295@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav296@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav297@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav298@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav299@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav300@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav301@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav302@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav303@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav304@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav305@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav306@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav307@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav308@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav309@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav310@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav311@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav312@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav313@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav314@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav315@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav316@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav317@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav318@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav319@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav320@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav321@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav322@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav323@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav324@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav325@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav326@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav327@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav328@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav329@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav330@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav331@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav332@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav333@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav334@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav335@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav336@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav337@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav338@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav339@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav340@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav341@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav342@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav343@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav344@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav345@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav346@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav347@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav348@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav349@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav350@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav351@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav352@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav353@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav354@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav355@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav356@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav357@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav358@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav359@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav360@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav361@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav362@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav363@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav364@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav365@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav366@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav367@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav368@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav369@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav370@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav371@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav372@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav373@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav374@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav375@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav376@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav377@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav378@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav379@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav380@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav381@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav382@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav383@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav384@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav385@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav386@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav387@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav388@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav389@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav390@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav391@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav392@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav393@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav394@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav395@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav396@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav397@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav398@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav399@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav400@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav401@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav402@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav403@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav404@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav405@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav406@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav407@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav408@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav409@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav410@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav411@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav412@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav413@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav414@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav415@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav416@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav417@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav418@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav419@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav420@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav421@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav422@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav423@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav424@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav425@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav426@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav427@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav428@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav429@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav430@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav431@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav432@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav433@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav434@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav435@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav436@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav437@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav438@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav439@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav440@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav441@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav442@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav443@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav444@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav445@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav446@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav447@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav448@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav449@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav450@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav451@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav452@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav453@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav454@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav455@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav456@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav457@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav458@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav459@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav460@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav461@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav462@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav463@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav464@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav465@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav466@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav467@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav468@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav469@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav470@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav471@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav472@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav473@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav474@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav475@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav476@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav477@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav478@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav479@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav480@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav481@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav482@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav483@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav484@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav485@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav486@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav487@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav488@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav489@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav490@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav491@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav492@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav493@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav494@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav495@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav496@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav497@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav498@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav499@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav500@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav501@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav502@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav503@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav504@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav505@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav506@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav507@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav508@gmail.com,All Users
|
||||
Vijay,Yadav,vjyaav509@gmail.com,All Users
|
||||
First Name,Last Name,Email,User Role,Group
|
||||
Vijay,Yadav,vjyaav1@gmail.com,Admin,
|
||||
Vijay,Yadav,vjyaav2@gmail.com,Builder,
|
||||
Vijay,Yadav,vjyaav3@gmail.com,Builder,
|
||||
Vijay,Yadav,vjyaav4@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav5@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav6@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav7@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav8@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav9@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav10@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav11@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav12@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav13@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav14@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav15@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav16@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav17@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav18@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav19@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav20@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav21@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav22@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav23@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav24@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav25@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav26@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav27@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav28@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav29@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav30@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav31@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav32@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav33@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav34@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav35@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav36@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav37@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav38@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav39@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav40@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav41@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav42@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav43@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav44@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav45@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav46@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav47@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav48@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav49@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav50@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav51@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav52@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav53@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav54@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav55@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav56@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav57@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav58@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav59@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav60@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav61@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav62@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav63@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav64@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav65@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav66@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav67@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav68@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav69@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav70@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav71@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav72@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav73@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav74@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav75@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav76@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav77@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav78@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav79@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav80@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav81@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav82@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav83@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav84@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav85@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav86@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav87@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav88@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav89@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav90@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav91@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav92@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav93@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav94@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav95@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav96@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav97@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav98@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav99@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav100@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav101@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav102@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav103@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav104@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav105@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav106@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav107@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav108@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav109@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav110@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav111@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav112@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav113@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav114@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav115@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav116@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav117@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav118@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav119@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav120@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav121@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav122@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav123@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav124@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav125@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav126@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav127@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav128@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav129@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav130@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav131@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav132@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav133@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav134@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav135@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav136@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav137@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav138@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav139@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav140@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav141@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav142@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav143@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav144@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav145@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav146@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav147@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav148@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav149@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav150@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav151@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav152@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav153@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav154@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav155@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav156@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav157@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav158@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav159@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav160@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav161@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav162@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav163@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav164@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav165@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav166@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav167@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav168@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav169@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav170@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav171@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav172@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav173@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav174@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav175@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav176@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav177@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav178@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav179@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav180@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav181@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav182@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav183@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav184@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav185@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav186@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav187@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav188@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav189@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav190@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav191@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav192@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav193@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav194@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav195@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav196@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav197@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav198@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav199@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav200@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav201@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav202@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav203@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav204@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav205@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav206@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav207@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav208@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav209@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav210@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav211@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav212@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav213@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav214@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav215@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav216@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav217@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav218@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav219@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav220@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav221@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav222@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav223@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav224@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav225@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav226@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav227@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav228@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav229@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav230@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav231@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav232@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav233@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav234@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav235@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav236@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav237@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav238@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav239@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav240@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav241@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav242@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav243@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav244@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav245@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav246@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav247@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav248@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav249@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav250@gmail.com,End User,
|
||||
Vijay,Yadav,vjyaav251@gmail.com,End User,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
First Name,Last Name,Email,Groups
|
||||
,,test12empty@gmail.com,All Users
|
||||
Test,Example,test12empty@gmail.com,All Users
|
||||
Test,Example,test14empty@gmail.com,All Users
|
||||
Test,Example,test14empty@gmail.com,All Users
|
||||
Test,Example,test16empty@gmail.com,All Users
|
||||
First Name,Last Name,Email,User Role,Group
|
||||
,,test12empty@gmail.com,Admin,Admin
|
||||
Test,Example,test12empty@gmail.com,Builder,Builder
|
||||
Test,Example,test14empty@gmail.com,End User,End User
|
||||
Test,Example,test14empty@gmail.com,End User,End User
|
||||
Test,Example,test16empty@gmail.com,End User,End User
|
||||
|
|
|
@ -1,12 +1,3 @@
|
|||
First Name,Last Name,Email,Groups
|
||||
Test,Example,test12@gmail.com,All-users
|
||||
Test,Example,test13@gmail.com,All-users
|
||||
Test,Example,test14@gmail.com,All-users
|
||||
Test,Example,test15@gmail.com,All-users
|
||||
Test,Example,test16@gmail.com,All-users
|
||||
Test,Example,test17@gmail.com,All-users
|
||||
Test,Example,test18@gmail.com,All-users
|
||||
Test,Example,test19@gmail.com,All-users
|
||||
Test,Example,test20@gmail.com,All-users
|
||||
Test,Example,test21@gmail.com,All-users
|
||||
Test,Example,test22@gmail.com,All-users
|
||||
First Name,Last Name,Email,User Role,Group
|
||||
Test,Example,test12@gmail.com,Admin,ABC
|
||||
Test,Example,test13@gmail.com,Builder,Test
|
||||
|
|
|
|||
|
|
|
@ -1,251 +1,251 @@
|
|||
First Name,Last Name,Email,Groups
|
||||
Test,Example,test12@gmail.com,All Users|Admin
|
||||
Test,Example,test13@gmail.com,All Users
|
||||
Test,Example,test14@gmail.com,All Users
|
||||
Test,Example,test15@gmail.com,All Users
|
||||
Test,Example,test16@gmail.com,All Users
|
||||
Test,Example,test17@gmail.com,All Users
|
||||
Test,Example,test18@gmail.com,All Users
|
||||
Test,Example,test19@gmail.com,All Users
|
||||
Test,Example,test20@gmail.com,All Users
|
||||
Test,Example,test21@gmail.com,All Users
|
||||
Test,Example,test22@gmail.com,All Users
|
||||
Test,Example,test23@gmail.com,All Users
|
||||
Test,Example,test24@gmail.com,All Users
|
||||
Test,Example,test25@gmail.com,All Users
|
||||
Test,Example,test26@gmail.com,All Users
|
||||
Test,Example,test27@gmail.com,All Users
|
||||
Test,Example,test28@gmail.com,All Users
|
||||
Test,Example,test29@gmail.com,All Users
|
||||
Test,Example,test30@gmail.com,All Users
|
||||
Test,Example,test31@gmail.com,All Users
|
||||
Test,Example,test32@gmail.com,All Users
|
||||
Test,Example,test33@gmail.com,All Users
|
||||
Test,Example,test34@gmail.com,All Users
|
||||
Test,Example,test35@gmail.com,All Users
|
||||
Test,Example,test36@gmail.com,All Users
|
||||
Test,Example,test37@gmail.com,All Users
|
||||
Test,Example,test38@gmail.com,All Users
|
||||
Test,Example,test39@gmail.com,All Users
|
||||
Test,Example,test40@gmail.com,All Users
|
||||
Test,Example,test41@gmail.com,All Users
|
||||
Test,Example,test42@gmail.com,All Users
|
||||
Test,Example,test43@gmail.com,All Users
|
||||
Test,Example,test44@gmail.com,All Users
|
||||
Test,Example,test45@gmail.com,All Users
|
||||
Test,Example,test46@gmail.com,All Users
|
||||
Test,Example,test47@gmail.com,All Users
|
||||
Test,Example,test48@gmail.com,All Users
|
||||
Test,Example,test49@gmail.com,All Users
|
||||
Test,Example,test50@gmail.com,All Users
|
||||
Test,Example,test51@gmail.com,All Users
|
||||
Test,Example,test52@gmail.com,All Users
|
||||
Test,Example,test53@gmail.com,All Users
|
||||
Test,Example,test54@gmail.com,All Users
|
||||
Test,Example,test55@gmail.com,All Users
|
||||
Test,Example,test56@gmail.com,All Users
|
||||
Test,Example,test57@gmail.com,All Users
|
||||
Test,Example,test58@gmail.com,All Users
|
||||
Test,Example,test59@gmail.com,All Users
|
||||
Test,Example,test60@gmail.com,All Users
|
||||
Test,Example,test61@gmail.com,All Users
|
||||
Test,Example,test62@gmail.com,All Users
|
||||
Test,Example,test63@gmail.com,All Users
|
||||
Test,Example,test64@gmail.com,All Users
|
||||
Test,Example,test65@gmail.com,All Users
|
||||
Test,Example,test66@gmail.com,All Users
|
||||
Test,Example,test67@gmail.com,All Users
|
||||
Test,Example,test68@gmail.com,All Users
|
||||
Test,Example,test69@gmail.com,All Users
|
||||
Test,Example,test70@gmail.com,All Users
|
||||
Test,Example,test71@gmail.com,All Users
|
||||
Test,Example,test72@gmail.com,All Users
|
||||
Test,Example,test73@gmail.com,All Users
|
||||
Test,Example,test74@gmail.com,All Users
|
||||
Test,Example,test75@gmail.com,All Users
|
||||
Test,Example,test76@gmail.com,All Users
|
||||
Test,Example,test77@gmail.com,All Users
|
||||
Test,Example,test78@gmail.com,All Users
|
||||
Test,Example,test79@gmail.com,All Users
|
||||
Test,Example,test80@gmail.com,All Users
|
||||
Test,Example,test81@gmail.com,All Users
|
||||
Test,Example,test82@gmail.com,All Users
|
||||
Test,Example,test83@gmail.com,All Users
|
||||
Test,Example,test84@gmail.com,All Users
|
||||
Test,Example,test85@gmail.com,All Users
|
||||
Test,Example,test86@gmail.com,All Users
|
||||
Test,Example,test87@gmail.com,All Users
|
||||
Test,Example,test88@gmail.com,All Users
|
||||
Test,Example,test89@gmail.com,All Users
|
||||
Test,Example,test90@gmail.com,All Users
|
||||
Test,Example,test91@gmail.com,All Users
|
||||
Test,Example,test92@gmail.com,All Users
|
||||
Test,Example,test93@gmail.com,All Users
|
||||
Test,Example,test94@gmail.com,All Users
|
||||
Test,Example,test95@gmail.com,All Users
|
||||
Test,Example,test96@gmail.com,All Users
|
||||
Test,Example,test97@gmail.com,All Users
|
||||
Test,Example,test98@gmail.com,All Users
|
||||
Test,Example,test99@gmail.com,All Users
|
||||
Test,Example,test100@gmail.com,All Users
|
||||
Test,Example,test101@gmail.com,All Users
|
||||
Test,Example,test102@gmail.com,All Users
|
||||
Test,Example,test103@gmail.com,All Users
|
||||
Test,Example,test104@gmail.com,All Users
|
||||
Test,Example,test105@gmail.com,All Users
|
||||
Test,Example,test106@gmail.com,All Users
|
||||
Test,Example,test107@gmail.com,All Users
|
||||
Test,Example,test108@gmail.com,All Users
|
||||
Test,Example,test109@gmail.com,All Users
|
||||
Test,Example,test110@gmail.com,All Users
|
||||
Test,Example,test111@gmail.com,All Users
|
||||
Test,Example,test112@gmail.com,All Users
|
||||
Test,Example,test113@gmail.com,All Users
|
||||
Test,Example,test114@gmail.com,All Users
|
||||
Test,Example,test115@gmail.com,All Users
|
||||
Test,Example,test116@gmail.com,All Users
|
||||
Test,Example,test117@gmail.com,All Users
|
||||
Test,Example,test118@gmail.com,All Users
|
||||
Test,Example,test119@gmail.com,All Users
|
||||
Test,Example,test120@gmail.com,All Users
|
||||
Test,Example,test121@gmail.com,All Users
|
||||
Test,Example,test122@gmail.com,All Users
|
||||
Test,Example,test123@gmail.com,All Users
|
||||
Test,Example,test124@gmail.com,All Users
|
||||
Test,Example,test125@gmail.com,All Users
|
||||
Test,Example,test126@gmail.com,All Users
|
||||
Test,Example,test127@gmail.com,All Users
|
||||
Test,Example,test128@gmail.com,All Users
|
||||
Test,Example,test129@gmail.com,All Users
|
||||
Test,Example,test130@gmail.com,All Users
|
||||
Test,Example,test131@gmail.com,All Users
|
||||
Test,Example,test132@gmail.com,All Users
|
||||
Test,Example,test133@gmail.com,All Users
|
||||
Test,Example,test134@gmail.com,All Users
|
||||
Test,Example,test135@gmail.com,All Users
|
||||
Test,Example,test136@gmail.com,All Users
|
||||
Test,Example,test137@gmail.com,All Users
|
||||
Test,Example,test138@gmail.com,All Users
|
||||
Test,Example,test139@gmail.com,All Users
|
||||
Test,Example,test140@gmail.com,All Users
|
||||
Test,Example,test141@gmail.com,All Users
|
||||
Test,Example,test142@gmail.com,All Users
|
||||
Test,Example,test143@gmail.com,All Users
|
||||
Test,Example,test144@gmail.com,All Users
|
||||
Test,Example,test145@gmail.com,All Users
|
||||
Test,Example,test146@gmail.com,All Users
|
||||
Test,Example,test147@gmail.com,All Users
|
||||
Test,Example,test148@gmail.com,All Users
|
||||
Test,Example,test149@gmail.com,All Users
|
||||
Test,Example,test150@gmail.com,All Users
|
||||
Test,Example,test151@gmail.com,All Users
|
||||
Test,Example,test152@gmail.com,All Users
|
||||
Test,Example,test153@gmail.com,All Users
|
||||
Test,Example,test154@gmail.com,All Users
|
||||
Test,Example,test155@gmail.com,All Users
|
||||
Test,Example,test156@gmail.com,All Users
|
||||
Test,Example,test157@gmail.com,All Users
|
||||
Test,Example,test158@gmail.com,All Users
|
||||
Test,Example,test159@gmail.com,All Users
|
||||
Test,Example,test160@gmail.com,All Users
|
||||
Test,Example,test161@gmail.com,All Users
|
||||
Test,Example,test162@gmail.com,All Users
|
||||
Test,Example,test163@gmail.com,All Users
|
||||
Test,Example,test164@gmail.com,All Users
|
||||
Test,Example,test165@gmail.com,All Users
|
||||
Test,Example,test166@gmail.com,All Users
|
||||
Test,Example,test167@gmail.com,All Users
|
||||
Test,Example,test168@gmail.com,All Users
|
||||
Test,Example,test169@gmail.com,All Users
|
||||
Test,Example,test170@gmail.com,All Users
|
||||
Test,Example,test171@gmail.com,All Users
|
||||
Test,Example,test172@gmail.com,All Users
|
||||
Test,Example,test173@gmail.com,All Users
|
||||
Test,Example,test174@gmail.com,All Users
|
||||
Test,Example,test175@gmail.com,All Users
|
||||
Test,Example,test176@gmail.com,All Users
|
||||
Test,Example,test177@gmail.com,All Users
|
||||
Test,Example,test178@gmail.com,All Users
|
||||
Test,Example,test179@gmail.com,All Users
|
||||
Test,Example,test180@gmail.com,All Users
|
||||
Test,Example,test181@gmail.com,All Users
|
||||
Test,Example,test182@gmail.com,All Users
|
||||
Test,Example,test183@gmail.com,All Users
|
||||
Test,Example,test184@gmail.com,All Users
|
||||
Test,Example,test185@gmail.com,All Users
|
||||
Test,Example,test186@gmail.com,All Users
|
||||
Test,Example,test187@gmail.com,All Users
|
||||
Test,Example,test188@gmail.com,All Users
|
||||
Test,Example,test189@gmail.com,All Users
|
||||
Test,Example,test190@gmail.com,All Users
|
||||
Test,Example,test191@gmail.com,All Users
|
||||
Test,Example,test192@gmail.com,All Users
|
||||
Test,Example,test193@gmail.com,All Users
|
||||
Test,Example,test194@gmail.com,All Users
|
||||
Test,Example,test195@gmail.com,All Users
|
||||
Test,Example,test196@gmail.com,All Users
|
||||
Test,Example,test197@gmail.com,All Users
|
||||
Test,Example,test198@gmail.com,All Users
|
||||
Test,Example,test199@gmail.com,All Users
|
||||
Test,Example,test200@gmail.com,All Users
|
||||
Test,Example,test201@gmail.com,All Users
|
||||
Test,Example,test202@gmail.com,All Users
|
||||
Test,Example,test203@gmail.com,All Users
|
||||
Test,Example,test204@gmail.com,All Users
|
||||
Test,Example,test205@gmail.com,All Users
|
||||
Test,Example,test206@gmail.com,All Users
|
||||
Test,Example,test207@gmail.com,All Users
|
||||
Test,Example,test208@gmail.com,All Users
|
||||
Test,Example,test209@gmail.com,All Users
|
||||
Test,Example,test210@gmail.com,All Users
|
||||
Test,Example,test211@gmail.com,All Users
|
||||
Test,Example,test212@gmail.com,All Users
|
||||
Test,Example,test213@gmail.com,All Users
|
||||
Test,Example,test214@gmail.com,All Users
|
||||
Test,Example,test215@gmail.com,All Users
|
||||
Test,Example,test216@gmail.com,All Users
|
||||
Test,Example,test217@gmail.com,All Users
|
||||
Test,Example,test218@gmail.com,All Users
|
||||
Test,Example,test219@gmail.com,All Users
|
||||
Test,Example,test220@gmail.com,All Users
|
||||
Test,Example,test221@gmail.com,All Users
|
||||
Test,Example,test222@gmail.com,All Users
|
||||
Test,Example,test223@gmail.com,All Users
|
||||
Test,Example,test224@gmail.com,All Users
|
||||
Test,Example,test225@gmail.com,All Users
|
||||
Test,Example,test226@gmail.com,All Users
|
||||
Test,Example,test227@gmail.com,All Users
|
||||
Test,Example,test228@gmail.com,All Users
|
||||
Test,Example,test229@gmail.com,All Users
|
||||
Test,Example,test230@gmail.com,All Users
|
||||
Test,Example,test231@gmail.com,All Users
|
||||
Test,Example,test232@gmail.com,All Users
|
||||
Test,Example,test233@gmail.com,All Users
|
||||
Test,Example,test234@gmail.com,All Users
|
||||
Test,Example,test235@gmail.com,All Users
|
||||
Test,Example,test236@gmail.com,All Users
|
||||
Test,Example,test237@gmail.com,All Users
|
||||
Test,Example,test238@gmail.com,All Users
|
||||
Test,Example,test239@gmail.com,All Users
|
||||
Test,Example,test240@gmail.com,All Users
|
||||
Test,Example,test241@gmail.com,All Users
|
||||
Test,Example,test242@gmail.com,All Users
|
||||
Test,Example,test243@gmail.com,All Users
|
||||
Test,Example,test244@gmail.com,All Users
|
||||
Test,Example,test245@gmail.com,All Users
|
||||
Test,Example,test246@gmail.com,All Users
|
||||
Test,Example,test247@gmail.com,All Users
|
||||
Test,Example,test248@gmail.com,All Users
|
||||
Test,Example,test249@gmail.com,All Users
|
||||
Test,Example,test250@gmail.com,All Users
|
||||
Test,Example,test251@gmail.com,All Users
|
||||
Test,Example,test252@gmail.com,All Users
|
||||
Test,Example,test253@gmail.com,All Users
|
||||
Test,Example,test254@gmail.com,All Users
|
||||
Test,Example,test255@gmail.com,All Users
|
||||
Test,Example,test256@gmail.com,All Users
|
||||
Test,Example,test257@gmail.com,All Users
|
||||
Test,Example,test258@gmail.com,All Users
|
||||
Test,Example,test259@gmail.com,All Users
|
||||
Test,Example,test260@gmail.com,All Users
|
||||
Test,Example,test261@gmail.com,All Users
|
||||
First Name,Last Name,Email,User Role,Group
|
||||
test,test,test1@gmail.com,Admin,Admin
|
||||
test,test,test2@gmail.com,Builder,Builder
|
||||
test,test,test3@gmail.com,Builder,Builder
|
||||
test,test,test4@gmail.com,End User,End User
|
||||
test,test,test5@gmail.com,End User,End User
|
||||
test,test,test6@gmail.com,End User,End User
|
||||
test,test,test7@gmail.com,End User,End User
|
||||
test,test,test8@gmail.com,End User,End User
|
||||
test,test,test9@gmail.com,End User,End User
|
||||
test,test,test10@gmail.com,End User,End User
|
||||
test,test,test11@gmail.com,End User,End User
|
||||
test,test,test12@gmail.com,End User,End User
|
||||
test,test,test13@gmail.com,End User,End User
|
||||
test,test,test14@gmail.com,End User,End User
|
||||
test,test,test15@gmail.com,End User,End User
|
||||
test,test,test16@gmail.com,End User,End User
|
||||
test,test,test17@gmail.com,End User,End User
|
||||
test,test,test18@gmail.com,End User,End User
|
||||
test,test,test19@gmail.com,End User,End User
|
||||
test,test,test20@gmail.com,End User,End User
|
||||
test,test,test21@gmail.com,End User,End User
|
||||
test,test,test22@gmail.com,End User,End User
|
||||
test,test,test23@gmail.com,End User,End User
|
||||
test,test,test24@gmail.com,End User,End User
|
||||
test,test,test25@gmail.com,End User,End User
|
||||
test,test,test26@gmail.com,End User,End User
|
||||
test,test,test27@gmail.com,End User,End User
|
||||
test,test,test28@gmail.com,End User,End User
|
||||
test,test,test29@gmail.com,End User,End User
|
||||
test,test,test30@gmail.com,End User,End User
|
||||
test,test,test31@gmail.com,End User,End User
|
||||
test,test,test32@gmail.com,End User,End User
|
||||
test,test,test33@gmail.com,End User,End User
|
||||
test,test,test34@gmail.com,End User,End User
|
||||
test,test,test35@gmail.com,End User,End User
|
||||
test,test,test36@gmail.com,End User,End User
|
||||
test,test,test37@gmail.com,End User,End User
|
||||
test,test,test38@gmail.com,End User,End User
|
||||
test,test,test39@gmail.com,End User,End User
|
||||
test,test,test40@gmail.com,End User,End User
|
||||
test,test,test41@gmail.com,End User,End User
|
||||
test,test,test42@gmail.com,End User,End User
|
||||
test,test,test43@gmail.com,End User,End User
|
||||
test,test,test44@gmail.com,End User,End User
|
||||
test,test,test45@gmail.com,End User,End User
|
||||
test,test,test46@gmail.com,End User,End User
|
||||
test,test,test47@gmail.com,End User,End User
|
||||
test,test,test48@gmail.com,End User,End User
|
||||
test,test,test49@gmail.com,End User,End User
|
||||
test,test,test50@gmail.com,End User,End User
|
||||
test,test,test51@gmail.com,End User,End User
|
||||
test,test,test52@gmail.com,End User,End User
|
||||
test,test,test53@gmail.com,End User,End User
|
||||
test,test,test54@gmail.com,End User,End User
|
||||
test,test,test55@gmail.com,End User,End User
|
||||
test,test,test56@gmail.com,End User,End User
|
||||
test,test,test57@gmail.com,End User,End User
|
||||
test,test,test58@gmail.com,End User,End User
|
||||
test,test,test59@gmail.com,End User,End User
|
||||
test,test,test60@gmail.com,End User,End User
|
||||
test,test,test61@gmail.com,End User,End User
|
||||
test,test,test62@gmail.com,End User,End User
|
||||
test,test,test63@gmail.com,End User,End User
|
||||
test,test,test64@gmail.com,End User,End User
|
||||
test,test,test65@gmail.com,End User,End User
|
||||
test,test,test66@gmail.com,End User,End User
|
||||
test,test,test67@gmail.com,End User,End User
|
||||
test,test,test68@gmail.com,End User,End User
|
||||
test,test,test69@gmail.com,End User,End User
|
||||
test,test,test70@gmail.com,End User,End User
|
||||
test,test,test71@gmail.com,End User,End User
|
||||
test,test,test72@gmail.com,End User,End User
|
||||
test,test,test73@gmail.com,End User,End User
|
||||
test,test,test74@gmail.com,End User,End User
|
||||
test,test,test75@gmail.com,End User,End User
|
||||
test,test,test76@gmail.com,End User,End User
|
||||
test,test,test77@gmail.com,End User,End User
|
||||
test,test,test78@gmail.com,End User,End User
|
||||
test,test,test79@gmail.com,End User,End User
|
||||
test,test,test80@gmail.com,End User,End User
|
||||
test,test,test81@gmail.com,End User,End User
|
||||
test,test,test82@gmail.com,End User,End User
|
||||
test,test,test83@gmail.com,End User,End User
|
||||
test,test,test84@gmail.com,End User,End User
|
||||
test,test,test85@gmail.com,End User,End User
|
||||
test,test,test86@gmail.com,End User,End User
|
||||
test,test,test87@gmail.com,End User,End User
|
||||
test,test,test88@gmail.com,End User,End User
|
||||
test,test,test89@gmail.com,End User,End User
|
||||
test,test,test90@gmail.com,End User,End User
|
||||
test,test,test91@gmail.com,End User,End User
|
||||
test,test,test92@gmail.com,End User,End User
|
||||
test,test,test93@gmail.com,End User,End User
|
||||
test,test,test94@gmail.com,End User,End User
|
||||
test,test,test95@gmail.com,End User,End User
|
||||
test,test,test96@gmail.com,End User,End User
|
||||
test,test,test97@gmail.com,End User,End User
|
||||
test,test,test98@gmail.com,End User,End User
|
||||
test,test,test99@gmail.com,End User,End User
|
||||
test,test,test100@gmail.com,End User,End User
|
||||
test,test,test101@gmail.com,End User,End User
|
||||
test,test,test102@gmail.com,End User,End User
|
||||
test,test,test103@gmail.com,End User,End User
|
||||
test,test,test104@gmail.com,End User,End User
|
||||
test,test,test105@gmail.com,End User,End User
|
||||
test,test,test106@gmail.com,End User,End User
|
||||
test,test,test107@gmail.com,End User,End User
|
||||
test,test,test108@gmail.com,End User,End User
|
||||
test,test,test109@gmail.com,End User,End User
|
||||
test,test,test110@gmail.com,End User,End User
|
||||
test,test,test111@gmail.com,End User,End User
|
||||
test,test,test112@gmail.com,End User,End User
|
||||
test,test,test113@gmail.com,End User,End User
|
||||
test,test,test114@gmail.com,End User,End User
|
||||
test,test,test115@gmail.com,End User,End User
|
||||
test,test,test116@gmail.com,End User,End User
|
||||
test,test,test117@gmail.com,End User,End User
|
||||
test,test,test118@gmail.com,End User,End User
|
||||
test,test,test119@gmail.com,End User,End User
|
||||
test,test,test120@gmail.com,End User,End User
|
||||
test,test,test121@gmail.com,End User,End User
|
||||
test,test,test122@gmail.com,End User,End User
|
||||
test,test,test123@gmail.com,End User,End User
|
||||
test,test,test124@gmail.com,End User,End User
|
||||
test,test,test125@gmail.com,End User,End User
|
||||
test,test,test126@gmail.com,End User,End User
|
||||
test,test,test127@gmail.com,End User,End User
|
||||
test,test,test128@gmail.com,End User,End User
|
||||
test,test,test129@gmail.com,End User,End User
|
||||
test,test,test130@gmail.com,End User,End User
|
||||
test,test,test131@gmail.com,End User,End User
|
||||
test,test,test132@gmail.com,End User,End User
|
||||
test,test,test133@gmail.com,End User,End User
|
||||
test,test,test134@gmail.com,End User,End User
|
||||
test,test,test135@gmail.com,End User,End User
|
||||
test,test,test136@gmail.com,End User,End User
|
||||
test,test,test137@gmail.com,End User,End User
|
||||
test,test,test138@gmail.com,End User,End User
|
||||
test,test,test139@gmail.com,End User,End User
|
||||
test,test,test140@gmail.com,End User,End User
|
||||
test,test,test141@gmail.com,End User,End User
|
||||
test,test,test142@gmail.com,End User,End User
|
||||
test,test,test143@gmail.com,End User,End User
|
||||
test,test,test144@gmail.com,End User,End User
|
||||
test,test,test145@gmail.com,End User,End User
|
||||
test,test,test146@gmail.com,End User,End User
|
||||
test,test,test147@gmail.com,End User,End User
|
||||
test,test,test148@gmail.com,End User,End User
|
||||
test,test,test149@gmail.com,End User,End User
|
||||
test,test,test150@gmail.com,End User,End User
|
||||
test,test,test151@gmail.com,End User,End User
|
||||
test,test,test152@gmail.com,End User,End User
|
||||
test,test,test153@gmail.com,End User,End User
|
||||
test,test,test154@gmail.com,End User,End User
|
||||
test,test,test155@gmail.com,End User,End User
|
||||
test,test,test156@gmail.com,End User,End User
|
||||
test,test,test157@gmail.com,End User,End User
|
||||
test,test,test158@gmail.com,End User,End User
|
||||
test,test,test159@gmail.com,End User,End User
|
||||
test,test,test160@gmail.com,End User,End User
|
||||
test,test,test161@gmail.com,End User,End User
|
||||
test,test,test162@gmail.com,End User,End User
|
||||
test,test,test163@gmail.com,End User,End User
|
||||
test,test,test164@gmail.com,End User,End User
|
||||
test,test,test165@gmail.com,End User,End User
|
||||
test,test,test166@gmail.com,End User,End User
|
||||
test,test,test167@gmail.com,End User,End User
|
||||
test,test,test168@gmail.com,End User,End User
|
||||
test,test,test169@gmail.com,End User,End User
|
||||
test,test,test170@gmail.com,End User,End User
|
||||
test,test,test171@gmail.com,End User,End User
|
||||
test,test,test172@gmail.com,End User,End User
|
||||
test,test,test173@gmail.com,End User,End User
|
||||
test,test,test174@gmail.com,End User,End User
|
||||
test,test,test175@gmail.com,End User,End User
|
||||
test,test,test176@gmail.com,End User,End User
|
||||
test,test,test177@gmail.com,End User,End User
|
||||
test,test,test178@gmail.com,End User,End User
|
||||
test,test,test179@gmail.com,End User,End User
|
||||
test,test,test180@gmail.com,End User,End User
|
||||
test,test,test181@gmail.com,End User,End User
|
||||
test,test,test182@gmail.com,End User,End User
|
||||
test,test,test183@gmail.com,End User,End User
|
||||
test,test,test184@gmail.com,End User,End User
|
||||
test,test,test185@gmail.com,End User,End User
|
||||
test,test,test186@gmail.com,End User,End User
|
||||
test,test,test187@gmail.com,End User,End User
|
||||
test,test,test188@gmail.com,End User,End User
|
||||
test,test,test189@gmail.com,End User,End User
|
||||
test,test,test190@gmail.com,End User,End User
|
||||
test,test,test191@gmail.com,End User,End User
|
||||
test,test,test192@gmail.com,End User,End User
|
||||
test,test,test193@gmail.com,End User,End User
|
||||
test,test,test194@gmail.com,End User,End User
|
||||
test,test,test195@gmail.com,End User,End User
|
||||
test,test,test196@gmail.com,End User,End User
|
||||
test,test,test197@gmail.com,End User,End User
|
||||
test,test,test198@gmail.com,End User,End User
|
||||
test,test,test199@gmail.com,End User,End User
|
||||
test,test,test200@gmail.com,End User,End User
|
||||
test,test,test201@gmail.com,End User,End User
|
||||
test,test,test202@gmail.com,End User,End User
|
||||
test,test,test203@gmail.com,End User,End User
|
||||
test,test,test204@gmail.com,End User,End User
|
||||
test,test,test205@gmail.com,End User,End User
|
||||
test,test,test206@gmail.com,End User,End User
|
||||
test,test,test207@gmail.com,End User,End User
|
||||
test,test,test208@gmail.com,End User,End User
|
||||
test,test,test209@gmail.com,End User,End User
|
||||
test,test,test210@gmail.com,End User,End User
|
||||
test,test,test211@gmail.com,End User,End User
|
||||
test,test,test212@gmail.com,End User,End User
|
||||
test,test,test213@gmail.com,End User,End User
|
||||
test,test,test214@gmail.com,End User,End User
|
||||
test,test,test215@gmail.com,End User,End User
|
||||
test,test,test216@gmail.com,End User,End User
|
||||
test,test,test217@gmail.com,End User,End User
|
||||
test,test,test218@gmail.com,End User,End User
|
||||
test,test,test219@gmail.com,End User,End User
|
||||
test,test,test220@gmail.com,End User,End User
|
||||
test,test,test221@gmail.com,End User,End User
|
||||
test,test,test222@gmail.com,End User,End User
|
||||
test,test,test223@gmail.com,End User,End User
|
||||
test,test,test224@gmail.com,End User,End User
|
||||
test,test,test225@gmail.com,End User,End User
|
||||
test,test,test226@gmail.com,End User,End User
|
||||
test,test,test227@gmail.com,End User,End User
|
||||
test,test,test228@gmail.com,End User,End User
|
||||
test,test,test229@gmail.com,End User,End User
|
||||
test,test,test230@gmail.com,End User,End User
|
||||
test,test,test231@gmail.com,End User,End User
|
||||
test,test,test232@gmail.com,End User,End User
|
||||
test,test,test233@gmail.com,End User,End User
|
||||
test,test,test234@gmail.com,End User,End User
|
||||
test,test,test235@gmail.com,End User,End User
|
||||
test,test,test236@gmail.com,End User,End User
|
||||
test,test,test237@gmail.com,End User,End User
|
||||
test,test,test238@gmail.com,End User,End User
|
||||
test,test,test239@gmail.com,End User,End User
|
||||
test,test,test240@gmail.com,End User,End User
|
||||
test,test,test241@gmail.com,End User,End User
|
||||
test,test,test242@gmail.com,End User,End User
|
||||
test,test,test243@gmail.com,End User,End User
|
||||
test,test,test244@gmail.com,End User,End User
|
||||
test,test,test245@gmail.com,End User,End User
|
||||
test,test,test246@gmail.com,End User,End User
|
||||
test,test,test247@gmail.com,End User,End User
|
||||
test,test,test248@gmail.com,End User,End User
|
||||
test,test,test249@gmail.com,End User,End User
|
||||
test,test,test250@gmail.com,End User,End User
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
First Name,Last Name,Email,Groups
|
||||
Test,Example,test12@example.com,All Users|Admin|Test
|
||||
Test,Example,test13@example.com,All Users
|
||||
Test,Example,test14@example.com,All Users
|
||||
Test,Example,test15@example.com,All Users
|
||||
Test,Example,test16@example.com,All Users
|
||||
Test,Example,test17@example.com,All Users
|
||||
First Name,Last Name,Email,User Role,Group
|
||||
Test,Example,test12@example.com,Admin,Admin|Builder
|
||||
Test,Example,test13@example.com,Buider,Buider|Test
|
||||
Test,Example,test14@example.com,End user,End user|Abc
|
||||
Test,Example,test15@example.com,End user,End user|Abc
|
||||
Test,Example,test16@example.com,End user,End user|Abc
|
||||
Test,Example,test17@example.com,End user,End user|Abc
|
||||
|
|
|
@ -1,251 +1,3 @@
|
|||
First Name,Last Name,Email,Groups
|
||||
Test,Example,test12@gmail.com,All Users|Test
|
||||
Test,Example,test13@gmail.com,All Users
|
||||
Test,Example,test14@gmail.com,All Users
|
||||
Test,Example,test15@gmail.com,All Users
|
||||
Test,Example,test16@gmail.com,All Users
|
||||
Test,Example,test17@gmail.com,All Users
|
||||
Test,Example,test18@gmail.com,All Users
|
||||
Test,Example,test19@gmail.com,All Users
|
||||
Test,Example,test20@gmail.com,All Users
|
||||
Test,Example,test21@gmail.com,All Users
|
||||
Test,Example,test22@gmail.com,All Users
|
||||
Test,Example,test23@gmail.com,All Users
|
||||
Test,Example,test24@gmail.com,All Users
|
||||
Test,Example,test25@gmail.com,All Users
|
||||
Test,Example,test26@gmail.com,All Users
|
||||
Test,Example,test27@gmail.com,All Users
|
||||
Test,Example,test28@gmail.com,All Users
|
||||
Test,Example,test29@gmail.com,All Users
|
||||
Test,Example,test30@gmail.com,All Users
|
||||
Test,Example,test31@gmail.com,All Users
|
||||
Test,Example,test32@gmail.com,All Users
|
||||
Test,Example,test33@gmail.com,All Users
|
||||
Test,Example,test34@gmail.com,All Users
|
||||
Test,Example,test35@gmail.com,All Users
|
||||
Test,Example,test36@gmail.com,All Users
|
||||
Test,Example,test37@gmail.com,All Users
|
||||
Test,Example,test38@gmail.com,All Users
|
||||
Test,Example,test39@gmail.com,All Users
|
||||
Test,Example,test40@gmail.com,All Users
|
||||
Test,Example,test41@gmail.com,All Users
|
||||
Test,Example,test42@gmail.com,All Users
|
||||
Test,Example,test43@gmail.com,All Users
|
||||
Test,Example,test44@gmail.com,All Users
|
||||
Test,Example,test45@gmail.com,All Users
|
||||
Test,Example,test46@gmail.com,All Users
|
||||
Test,Example,test47@gmail.com,All Users
|
||||
Test,Example,test48@gmail.com,All Users
|
||||
Test,Example,test49@gmail.com,All Users
|
||||
Test,Example,test50@gmail.com,All Users
|
||||
Test,Example,test51@gmail.com,All Users
|
||||
Test,Example,test52@gmail.com,All Users
|
||||
Test,Example,test53@gmail.com,All Users
|
||||
Test,Example,test54@gmail.com,All Users
|
||||
Test,Example,test55@gmail.com,All Users
|
||||
Test,Example,test56@gmail.com,All Users
|
||||
Test,Example,test57@gmail.com,All Users
|
||||
Test,Example,test58@gmail.com,All Users
|
||||
Test,Example,test59@gmail.com,All Users
|
||||
Test,Example,test60@gmail.com,All Users
|
||||
Test,Example,test61@gmail.com,All Users
|
||||
Test,Example,test62@gmail.com,All Users
|
||||
Test,Example,test63@gmail.com,All Users
|
||||
Test,Example,test64@gmail.com,All Users
|
||||
Test,Example,test65@gmail.com,All Users
|
||||
Test,Example,test66@gmail.com,All Users
|
||||
Test,Example,test67@gmail.com,All Users
|
||||
Test,Example,test68@gmail.com,All Users
|
||||
Test,Example,test69@gmail.com,All Users
|
||||
Test,Example,test70@gmail.com,All Users
|
||||
Test,Example,test71@gmail.com,All Users
|
||||
Test,Example,test72@gmail.com,All Users
|
||||
Test,Example,test73@gmail.com,All Users
|
||||
Test,Example,test74@gmail.com,All Users
|
||||
Test,Example,test75@gmail.com,All Users
|
||||
Test,Example,test76@gmail.com,All Users
|
||||
Test,Example,test77@gmail.com,All Users
|
||||
Test,Example,test78@gmail.com,All Users
|
||||
Test,Example,test79@gmail.com,All Users
|
||||
Test,Example,test80@gmail.com,All Users
|
||||
Test,Example,test81@gmail.com,All Users
|
||||
Test,Example,test82@gmail.com,All Users
|
||||
Test,Example,test83@gmail.com,All Users
|
||||
Test,Example,test84@gmail.com,All Users
|
||||
Test,Example,test85@gmail.com,All Users
|
||||
Test,Example,test86@gmail.com,All Users
|
||||
Test,Example,test87@gmail.com,All Users
|
||||
Test,Example,test88@gmail.com,All Users
|
||||
Test,Example,test89@gmail.com,All Users
|
||||
Test,Example,test90@gmail.com,All Users
|
||||
Test,Example,test91@gmail.com,All Users
|
||||
Test,Example,test92@gmail.com,All Users
|
||||
Test,Example,test93@gmail.com,All Users
|
||||
Test,Example,test94@gmail.com,All Users
|
||||
Test,Example,test95@gmail.com,All Users
|
||||
Test,Example,test96@gmail.com,All Users
|
||||
Test,Example,test97@gmail.com,All Users
|
||||
Test,Example,test98@gmail.com,All Users
|
||||
Test,Example,test99@gmail.com,All Users
|
||||
Test,Example,test100@gmail.com,All Users
|
||||
Test,Example,test101@gmail.com,All Users
|
||||
Test,Example,test102@gmail.com,All Users
|
||||
Test,Example,test103@gmail.com,All Users
|
||||
Test,Example,test104@gmail.com,All Users
|
||||
Test,Example,test105@gmail.com,All Users
|
||||
Test,Example,test106@gmail.com,All Users
|
||||
Test,Example,test107@gmail.com,All Users
|
||||
Test,Example,test108@gmail.com,All Users
|
||||
Test,Example,test109@gmail.com,All Users
|
||||
Test,Example,test110@gmail.com,All Users
|
||||
Test,Example,test111@gmail.com,All Users
|
||||
Test,Example,test112@gmail.com,All Users
|
||||
Test,Example,test113@gmail.com,All Users
|
||||
Test,Example,test114@gmail.com,All Users
|
||||
Test,Example,test115@gmail.com,All Users
|
||||
Test,Example,test116@gmail.com,All Users
|
||||
Test,Example,test117@gmail.com,All Users
|
||||
Test,Example,test118@gmail.com,All Users
|
||||
Test,Example,test119@gmail.com,All Users
|
||||
Test,Example,test120@gmail.com,All Users
|
||||
Test,Example,test121@gmail.com,All Users
|
||||
Test,Example,test122@gmail.com,All Users
|
||||
Test,Example,test123@gmail.com,All Users
|
||||
Test,Example,test124@gmail.com,All Users
|
||||
Test,Example,test125@gmail.com,All Users
|
||||
Test,Example,test126@gmail.com,All Users
|
||||
Test,Example,test127@gmail.com,All Users
|
||||
Test,Example,test128@gmail.com,All Users
|
||||
Test,Example,test129@gmail.com,All Users
|
||||
Test,Example,test130@gmail.com,All Users
|
||||
Test,Example,test131@gmail.com,All Users
|
||||
Test,Example,test132@gmail.com,All Users
|
||||
Test,Example,test133@gmail.com,All Users
|
||||
Test,Example,test134@gmail.com,All Users
|
||||
Test,Example,test135@gmail.com,All Users
|
||||
Test,Example,test136@gmail.com,All Users
|
||||
Test,Example,test137@gmail.com,All Users
|
||||
Test,Example,test138@gmail.com,All Users
|
||||
Test,Example,test139@gmail.com,All Users
|
||||
Test,Example,test140@gmail.com,All Users
|
||||
Test,Example,test141@gmail.com,All Users
|
||||
Test,Example,test142@gmail.com,All Users
|
||||
Test,Example,test143@gmail.com,All Users
|
||||
Test,Example,test144@gmail.com,All Users
|
||||
Test,Example,test145@gmail.com,All Users
|
||||
Test,Example,test146@gmail.com,All Users
|
||||
Test,Example,test147@gmail.com,All Users
|
||||
Test,Example,test148@gmail.com,All Users
|
||||
Test,Example,test149@gmail.com,All Users
|
||||
Test,Example,test150@gmail.com,All Users
|
||||
Test,Example,test151@gmail.com,All Users
|
||||
Test,Example,test152@gmail.com,All Users
|
||||
Test,Example,test153@gmail.com,All Users
|
||||
Test,Example,test154@gmail.com,All Users
|
||||
Test,Example,test155@gmail.com,All Users
|
||||
Test,Example,test156@gmail.com,All Users
|
||||
Test,Example,test157@gmail.com,All Users
|
||||
Test,Example,test158@gmail.com,All Users
|
||||
Test,Example,test159@gmail.com,All Users
|
||||
Test,Example,test160@gmail.com,All Users
|
||||
Test,Example,test161@gmail.com,All Users
|
||||
Test,Example,test162@gmail.com,All Users
|
||||
Test,Example,test163@gmail.com,All Users
|
||||
Test,Example,test164@gmail.com,All Users
|
||||
Test,Example,test165@gmail.com,All Users
|
||||
Test,Example,test166@gmail.com,All Users
|
||||
Test,Example,test167@gmail.com,All Users
|
||||
Test,Example,test168@gmail.com,All Users
|
||||
Test,Example,test169@gmail.com,All Users
|
||||
Test,Example,test170@gmail.com,All Users
|
||||
Test,Example,test171@gmail.com,All Users
|
||||
Test,Example,test172@gmail.com,All Users
|
||||
Test,Example,test173@gmail.com,All Users
|
||||
Test,Example,test174@gmail.com,All Users
|
||||
Test,Example,test175@gmail.com,All Users
|
||||
Test,Example,test176@gmail.com,All Users
|
||||
Test,Example,test177@gmail.com,All Users
|
||||
Test,Example,test178@gmail.com,All Users
|
||||
Test,Example,test179@gmail.com,All Users
|
||||
Test,Example,test180@gmail.com,All Users
|
||||
Test,Example,test181@gmail.com,All Users
|
||||
Test,Example,test182@gmail.com,All Users
|
||||
Test,Example,test183@gmail.com,All Users
|
||||
Test,Example,test184@gmail.com,All Users
|
||||
Test,Example,test185@gmail.com,All Users
|
||||
Test,Example,test186@gmail.com,All Users
|
||||
Test,Example,test187@gmail.com,All Users
|
||||
Test,Example,test188@gmail.com,All Users
|
||||
Test,Example,test189@gmail.com,All Users
|
||||
Test,Example,test190@gmail.com,All Users
|
||||
Test,Example,test191@gmail.com,All Users
|
||||
Test,Example,test192@gmail.com,All Users
|
||||
Test,Example,test193@gmail.com,All Users
|
||||
Test,Example,test194@gmail.com,All Users
|
||||
Test,Example,test195@gmail.com,All Users
|
||||
Test,Example,test196@gmail.com,All Users
|
||||
Test,Example,test197@gmail.com,All Users
|
||||
Test,Example,test198@gmail.com,All Users
|
||||
Test,Example,test199@gmail.com,All Users
|
||||
Test,Example,test200@gmail.com,All Users
|
||||
Test,Example,test201@gmail.com,All Users
|
||||
Test,Example,test202@gmail.com,All Users
|
||||
Test,Example,test203@gmail.com,All Users
|
||||
Test,Example,test204@gmail.com,All Users
|
||||
Test,Example,test205@gmail.com,All Users
|
||||
Test,Example,test206@gmail.com,All Users
|
||||
Test,Example,test207@gmail.com,All Users
|
||||
Test,Example,test208@gmail.com,All Users
|
||||
Test,Example,test209@gmail.com,All Users
|
||||
Test,Example,test210@gmail.com,All Users
|
||||
Test,Example,test211@gmail.com,All Users
|
||||
Test,Example,test212@gmail.com,All Users
|
||||
Test,Example,test213@gmail.com,All Users
|
||||
Test,Example,test214@gmail.com,All Users
|
||||
Test,Example,test215@gmail.com,All Users
|
||||
Test,Example,test216@gmail.com,All Users
|
||||
Test,Example,test217@gmail.com,All Users
|
||||
Test,Example,test218@gmail.com,All Users
|
||||
Test,Example,test219@gmail.com,All Users
|
||||
Test,Example,test220@gmail.com,All Users
|
||||
Test,Example,test221@gmail.com,All Users
|
||||
Test,Example,test222@gmail.com,All Users
|
||||
Test,Example,test223@gmail.com,All Users
|
||||
Test,Example,test224@gmail.com,All Users
|
||||
Test,Example,test225@gmail.com,All Users
|
||||
Test,Example,test226@gmail.com,All Users
|
||||
Test,Example,test227@gmail.com,All Users
|
||||
Test,Example,test228@gmail.com,All Users
|
||||
Test,Example,test229@gmail.com,All Users
|
||||
Test,Example,test230@gmail.com,All Users
|
||||
Test,Example,test231@gmail.com,All Users
|
||||
Test,Example,test232@gmail.com,All Users
|
||||
Test,Example,test233@gmail.com,All Users
|
||||
Test,Example,test234@gmail.com,All Users
|
||||
Test,Example,test235@gmail.com,All Users
|
||||
Test,Example,test236@gmail.com,All Users
|
||||
Test,Example,test237@gmail.com,All Users
|
||||
Test,Example,test238@gmail.com,All Users
|
||||
Test,Example,test239@gmail.com,All Users
|
||||
Test,Example,test240@gmail.com,All Users
|
||||
Test,Example,test241@gmail.com,All Users
|
||||
Test,Example,test242@gmail.com,All Users
|
||||
Test,Example,test243@gmail.com,All Users
|
||||
Test,Example,test244@gmail.com,All Users
|
||||
Test,Example,test245@gmail.com,All Users
|
||||
Test,Example,test246@gmail.com,All Users
|
||||
Test,Example,test247@gmail.com,All Users
|
||||
Test,Example,test248@gmail.com,All Users
|
||||
Test,Example,test249@gmail.com,All Users
|
||||
Test,Example,test250@gmail.com,All Users
|
||||
Test,Example,test251@gmail.com,All Users
|
||||
Test,Example,test252@gmail.com,All Users
|
||||
Test,Example,test253@gmail.com,All Users
|
||||
Test,Example,test254@gmail.com,All Users
|
||||
Test,Example,test255@gmail.com,All Users
|
||||
Test,Example,test256@gmail.com,All Users
|
||||
Test,Example,test257@gmail.com,All Users
|
||||
Test,Example,test258@gmail.com,All Users
|
||||
Test,Example,test259@gmail.com,All Users
|
||||
Test,Example,test260@gmail.com,All Users
|
||||
Test,Example,test261@gmail.com,All Users
|
||||
First Name,Last Name,Email,User Role,Group
|
||||
test,test,demo1@gmail.com,Admin,test
|
||||
test,test,demo2@gmail.com,Builder,abc
|
||||
|
|
|
|||
|
|
|
@ -1,6 +1,4 @@
|
|||
First Name,Last Name,Email,Groups
|
||||
Test,Example,test12@gmail.com,All Users
|
||||
Test,Example,test12@gmail.com,All Users
|
||||
Test,Example,test14@gmail.com,All Users
|
||||
Test,Example,test14@gmail.com,All Users
|
||||
Test,Example,test16@gmail.com,All Users
|
||||
First Name,Last Name,Email,User Role,Group
|
||||
test,test,demo11@gmail.com,Admin,
|
||||
test,test,demo11@gmail.com,Builder,
|
||||
test,test,demo12@gmail.com,Builder,
|
||||
|
|
|
|||
|
|
|
@ -1,12 +1,11 @@
|
|||
First Name,Last Name,Email,Groups
|
||||
Test,Example,,All Users
|
||||
Test,Example,,All Users
|
||||
Test,Example,,All Users
|
||||
Test,Example,,All Users
|
||||
Test,Example,,All Users
|
||||
Test,Example,,All Users
|
||||
Test,Example,,All Users
|
||||
Test,Example,,All Users
|
||||
Test,Example,,All Users
|
||||
Test,Example,,All Users
|
||||
Test,Example,,All Users
|
||||
First Name,Last Name,Email,User Role,Group
|
||||
test,test,,Admin,Admin
|
||||
test,test,,Builder,Builder
|
||||
test,test,,Builder,Builder
|
||||
test,test,,End User,End User
|
||||
test,test,,End User,End User
|
||||
test,test,,End User,End User
|
||||
test,test,,End User,End User
|
||||
test,test,,End User,End User
|
||||
test,test,,End User,End User
|
||||
test,test,,End User,End User
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
First Name,Last Name,Email,Groups
|
||||
,Example,test12withoutfirstname@gmail.com,All Users
|
||||
,Example,test13withoutfirstname@gmail.com,All Users
|
||||
,Example,test14withoutfirstname@gmail.com,All Users
|
||||
,Example,test15withoutfirstname@gmail.com,All Users
|
||||
,Example,test16withoutfirstname@gmail.com,All Users
|
||||
First Name,Last Name,Email,User Role,Group
|
||||
,test,demo1@gmail.com,Admin,
|
||||
,test,demo2@gmail.com,Builder,
|
||||
,test,demo3@gmail.com,End User,
|
||||
|
|
|
|||
|
|
|
@ -1,6 +1,6 @@
|
|||
First Name,Last Name,Email,Groups
|
||||
Test,Example,test12@gmail.com,
|
||||
Test,Example,test13@gmail.com,
|
||||
Test,Example,test14@gmail.com,
|
||||
Test,Example,test15@gmail.com,
|
||||
Test,Example,test16@gmail.com,
|
||||
First Name,Last Name,Email,User Role,Group
|
||||
Test,Example,test12@gmail.com,Admin,
|
||||
Test,Example,test13@gmail.com,Builder,
|
||||
Test,Example,test14@gmail.com,End User,
|
||||
Test,Example,test15@gmail.com,End User,
|
||||
Test,Example,test16@gmail.com,End User,
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
First Name,Last Name,Email,Groups
|
||||
Test,,test12withoutlastname@gmail.com,All Users
|
||||
Test,,test13withoutlastname@gmail.com,All Users
|
||||
Test,,test14withoutlastname@gmail.com,All Users
|
||||
Test,,test15withoutlastname@gmail.com,All Users
|
||||
Test,,test16withoutlastname@gmail.com,All Users
|
||||
First Name,Last Name,Email,User Role,Group
|
||||
test,,withoutlastname1@gmail.com,Admin,Admin
|
||||
test,,withoutlastname2@gmail.com,Builder,Builder
|
||||
test,,withoutlastname3@gmail.com,Builder,Builder
|
||||
test,,withoutlastname4@gmail.com,End User,End User
|
||||
test,,withoutlastname5@gmail.com,End User,End User
|
||||
test,,withoutlastname6@gmail.com,End User,End User
|
||||
test,,withoutlastname7@gmail.com,End User,End User
|
||||
test,,withoutlastname8@gmail.com,End User,End User
|
||||
test,,withoutlastname9@gmail.com,End User,End User
|
||||
test,,withoutlastname10@gmail.com,End User,End User
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
First Name,Last Name,Email,Groups
|
||||
,,test12@gmail.com,All Users
|
||||
,,test13@gmail.com,All Users
|
||||
,,test14@gmail.com,All Users
|
||||
,,test15@gmail.com,All Users
|
||||
,,test16@gmail.com,All Users
|
||||
,,test17@gmail.com,All Users
|
||||
,,test18@gmail.com,All Users
|
||||
,,test19@gmail.com,All Users
|
||||
,,test20@gmail.com,All Users
|
||||
,,test21@gmail.com,All Users
|
||||
,,test22@gmail.com,All Users
|
||||
First Name,Last Name,Email,User Role,Group
|
||||
,,withoutname1@gmail.com,Admin,Admin
|
||||
,,withoutname2@gmail.com,Builder,Builder
|
||||
,,withoutname3@gmail.com,Builder,Builder
|
||||
,,withoutname4@gmail.com,End User,End User
|
||||
,,withoutname5@gmail.com,End User,End User
|
||||
,,withoutname6@gmail.com,End User,End User
|
||||
,,withoutname7@gmail.com,End User,End User
|
||||
,,withoutname8@gmail.com,End User,End User
|
||||
,,withoutname9@gmail.com,End User,End User
|
||||
,,withoutname10@gmail.com,End User,End User
|
||||
|
|
|
@ -11,9 +11,9 @@ import {
|
|||
|
||||
export const login = () => {
|
||||
cy.visit("/");
|
||||
cy.clearAndType(commonSelectors.workEmailInputField, "dev@tooljet.io");
|
||||
cy.clearAndType(commonSelectors.passwordInputField, "password");
|
||||
cy.get(commonSelectors.loginButton).click();
|
||||
cy.clearAndType(onboardingSelectors.emailInput, "dev@tooljet.io");
|
||||
cy.clearAndType(onboardingSelectors.passwordInput, "password");
|
||||
cy.get(onboardingSelectors.signInButton).click();
|
||||
};
|
||||
|
||||
export const modifyAndVerifyAppCardIcon = (appName) => {
|
||||
|
|
|
|||
|
|
@ -235,18 +235,18 @@ export const workspaceLoginPageElements = (workspaceName) => {
|
|||
};
|
||||
|
||||
export const passwordLoginVisible = () => {
|
||||
cy.get(commonSelectors.workEmailInputField).should("be.visible");
|
||||
cy.get(commonSelectors.passwordInputField).should("be.visible");
|
||||
cy.get(commonSelectors.loginButton).verifyVisibleElement(
|
||||
cy.get(onboardingSelectors.emailInput).should("be.visible");
|
||||
cy.get(onboardingSelectors.passwordInput).should("be.visible");
|
||||
cy.get(onboardingSelectors.signInButton).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.loginButton
|
||||
);
|
||||
};
|
||||
|
||||
export const workspaceLogin = (workspaceName) => {
|
||||
cy.clearAndType(commonSelectors.workEmailInputField, "dev@tooljet.io");
|
||||
cy.clearAndType(commonSelectors.passwordInputField, "password");
|
||||
cy.get(commonSelectors.loginButton).click();
|
||||
cy.clearAndType(onboardingSelectors.emailInput, "dev@tooljet.io");
|
||||
cy.clearAndType(onboardingSelectors.passwordInput, "password");
|
||||
cy.get(onboardingSelectors.signInButton).click();
|
||||
cy.wait(2000);
|
||||
cy.get(commonSelectors.homePageLogo).should("be.visible");
|
||||
cy.get(commonSelectors.workspaceName).verifyVisibleElement(
|
||||
|
|
@ -295,13 +295,13 @@ export const signInPageElements = () => {
|
|||
"have.text",
|
||||
commonText.forgotPasswordLink
|
||||
);
|
||||
cy.get(commonSelectors.loginButton).verifyVisibleElement(
|
||||
cy.get(onboardingSelectors.signInButton).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.loginButton
|
||||
);
|
||||
|
||||
cy.get(commonSelectors.workEmailInputField).should("be.visible");
|
||||
cy.get(commonSelectors.passwordInputField).should("be.visible");
|
||||
cy.get(onboardingSelectors.emailInput).should("be.visible");
|
||||
cy.get(onboardingSelectors.passwordInput).should("be.visible");
|
||||
|
||||
cy.get("body").then(($el) => {
|
||||
if ($el.text().includes("Google")) {
|
||||
|
|
@ -477,7 +477,7 @@ export const invitePageElements = () => {
|
|||
"have.text",
|
||||
commonText.passwordLabel
|
||||
);
|
||||
cy.get(commonSelectors.passwordInputField).should("be.visible");
|
||||
cy.get(onboardingSelectors.passwordInput).should("be.visible");
|
||||
cy.get(commonSelectors.acceptInviteButton).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.acceptInviteButton
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ import { ssoSelector } from "Selectors/manageSSO";
|
|||
import { ssoText } from "Texts/manageSSO";
|
||||
import * as common from "Support/utils/common";
|
||||
import { commonText } from "Texts/common";
|
||||
import { onboardingSelectors } from "Selectors/onboarding";
|
||||
|
||||
|
||||
export const manageUsersElements = () => {
|
||||
cy.get(commonSelectors.breadcrumbTitle).should(($el) => {
|
||||
|
|
@ -150,19 +152,19 @@ export const manageUsersElements = () => {
|
|||
export const inviteUser = (firstName, email) => {
|
||||
cy.userInviteApi(firstName, email);
|
||||
fetchAndVisitInviteLink(email);
|
||||
cy.clearAndType(commonSelectors.passwordInputField, "password");
|
||||
cy.clearAndType(onboardingSelectors.passwordInput, "password");
|
||||
cy.get(commonSelectors.acceptInviteButton).click();
|
||||
};
|
||||
|
||||
export const confirmInviteElements = (email) => {
|
||||
|
||||
cy.get(commonSelectors.SignUpSectionHeader).verifyVisibleElement(
|
||||
cy.get(commonSelectors.signUpSectionHeader).verifyVisibleElement(
|
||||
"have.text", "Sign up");
|
||||
cy.get('[data-cy="workspace-signup-header"]').verifyVisibleElement(
|
||||
"have.text", "Sign up to the workspace - My workspace");
|
||||
cy.get('[data-cy="signup-info"]').verifyVisibleElement(
|
||||
"have.text", "Sign up to the workspace - My workspace. ");
|
||||
|
||||
cy.verifyLabel("Email")
|
||||
cy.verifyLabel("Create a password")
|
||||
// cy.verifyLabel("Email")
|
||||
// cy.verifyLabel("Create a password")
|
||||
cy.get(commonSelectors.invitedUserEmail).verifyVisibleElement(
|
||||
"have.text", email);
|
||||
|
||||
|
|
@ -215,7 +217,6 @@ export const bulkUserUpload = (file, fileName, toastMessage) => {
|
|||
.should("be.visible")
|
||||
.and("have.text", toastMessage);
|
||||
cy.get(usersSelector.toastCloseButton).click();
|
||||
|
||||
cy.wait(200);
|
||||
};
|
||||
|
||||
|
|
@ -242,8 +243,8 @@ export const copyInvitationLink = (firstName, email) => {
|
|||
|
||||
export const fillUserInviteForm = (firstName, email) => {
|
||||
cy.get(usersSelector.buttonAddUsers).click();
|
||||
cy.clearAndType(commonSelectors.inputFieldFullName, firstName);
|
||||
cy.clearAndType(commonSelectors.inputFieldEmailAddress, email);
|
||||
cy.clearAndType(onboardingSelectors.nameInput, firstName);
|
||||
cy.clearAndType(onboardingSelectors.signupEmailInput, email);
|
||||
};
|
||||
|
||||
export const selectUserGroup = (groupName) => {
|
||||
|
|
@ -293,7 +294,8 @@ export const inviteUserWithUserGroups = (
|
|||
|
||||
cy.wait(1000);
|
||||
fetchAndVisitInviteLink(email);
|
||||
cy.clearAndType(commonSelectors.passwordInputField, "password");
|
||||
cy.wait(2000);
|
||||
cy.clearAndType(onboardingSelectors.loginPasswordInput, "password");
|
||||
// cy.intercept('GET', '/api/organizations').as('org')
|
||||
cy.get(commonSelectors.signUpButton).click();
|
||||
cy.wait(2000);
|
||||
|
|
@ -372,7 +374,7 @@ export const inviteUserWithUserRole = (
|
|||
|
||||
cy.wait(1000);
|
||||
fetchAndVisitInviteLink(email);
|
||||
cy.clearAndType(commonSelectors.passwordInputField, "password");
|
||||
cy.clearAndType(onboardingSelectors.loginPasswordInput, "password");
|
||||
cy.get(commonSelectors.signUpButton).click();
|
||||
cy.wait(2000);
|
||||
cy.get(commonSelectors.acceptInviteButton).click();
|
||||
|
|
|
|||
|
|
@ -8,11 +8,12 @@ import {
|
|||
import { navigateToManageUsers, logout } from "Support/utils/common";
|
||||
import { ssoSelector } from "Selectors/manageSSO";
|
||||
import { ssoText } from "Texts/manageSSO";
|
||||
import { onboardingSelectors } from "Selectors/onboarding";
|
||||
|
||||
|
||||
export const verifyConfirmEmailPage = (email) => {
|
||||
cy.get(commonSelectors.pageLogo).should("be.visible");
|
||||
cy.get(commonSelectors.emailImage).should("be.visible");
|
||||
cy.get(commonSelectors.onboardingPageHeader).verifyVisibleElement(
|
||||
cy.get('[data-cy="check-your-mail-header"]').verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.emailPageHeader
|
||||
);
|
||||
|
|
@ -31,32 +32,17 @@ export const verifyConfirmEmailPage = (email) => {
|
|||
"have.text",
|
||||
commonText.onboardingSeperatorText
|
||||
);
|
||||
|
||||
cy.get(commonSelectors.resendEmailButton).should("be.visible");
|
||||
cy.get(commonSelectors.editEmailButton).verifyVisibleElement(
|
||||
cy.get('[data-cy="back-to-signup"]').verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.editEmailButton
|
||||
"Back to sign up"
|
||||
);
|
||||
};
|
||||
|
||||
export const verifyConfirmPageElements = () => {
|
||||
cy.get(commonSelectors.pageLogo).should("be.visible");
|
||||
cy.get(commonSelectors.emailImage).should("be.visible");
|
||||
cy.get(commonSelectors.onboardingPageHeader).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.emailVerifiedText
|
||||
);
|
||||
|
||||
cy.get(commonSelectors.onboardingPageDescription).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.continueToSetUp
|
||||
);
|
||||
cy.get(commonSelectors.setUpToolJetButton).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.setUpToolJetButton
|
||||
);
|
||||
};
|
||||
|
||||
export const verifyOnboardingQuestions = (fullName, workspaceName) => {
|
||||
cy.wait(5000);
|
||||
cy.get(commonSelectors.pageLogo).should("be.visible");
|
||||
cy.get(commonSelectors.userAccountNameAvatar).should("be.visible");
|
||||
cy.get(commonSelectors.createAccountCheckMark).should("be.visible");
|
||||
|
|
@ -125,7 +111,7 @@ export const verifyOnboardingQuestions = (fullName, workspaceName) => {
|
|||
|
||||
export const verifyInvalidInvitationLink = () => {
|
||||
cy.get(commonSelectors.pageLogo).should("be.visible");
|
||||
cy.get(commonSelectors.emailImage).should("be.visible");
|
||||
// cy.get(commonSelectors.emailImage).should("be.visible");
|
||||
|
||||
cy.get(commonSelectors.onboardingPageHeader).verifyVisibleElement(
|
||||
"have.text",
|
||||
|
|
@ -136,20 +122,24 @@ export const verifyInvalidInvitationLink = () => {
|
|||
commonText.inalidInvitationLinkDescription
|
||||
);
|
||||
|
||||
cy.get(commonSelectors.backtoSignUpButton).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.backtoSignUpButton
|
||||
);
|
||||
// cy.get(commonSelectors.backtoSignUpButton).verifyVisibleElement(
|
||||
// "have.text",
|
||||
// commonText.backtoSignUpButton
|
||||
// );
|
||||
};
|
||||
|
||||
export const userSignUp = (fullName, email, workspaceName) => {
|
||||
let invitationLink;
|
||||
cy.intercept("GET", "/api/organizations/public-configs").as("publicConfig");
|
||||
cy.visit("/");
|
||||
cy.wait(1000);
|
||||
cy.get(commonSelectors.createAnAccountLink).realClick();
|
||||
cy.clearAndType(commonSelectors.nameInputField, fullName);
|
||||
cy.clearAndType(commonSelectors.emailInputField, email);
|
||||
cy.clearAndType(commonSelectors.passwordInputField, commonText.password);
|
||||
cy.wait("@publicConfig"); // Wait for the API response
|
||||
cy.get(commonSelectors.createAnAccountLink).realClick(); // Proceed to click the link
|
||||
cy.get(onboardingSelectors.nameInput).should('not.be.disabled');
|
||||
cy.wait(3000)
|
||||
cy.get(onboardingSelectors.nameInput).clear();
|
||||
cy.get(onboardingSelectors.nameInput).type(fullName);
|
||||
cy.clearAndType(onboardingSelectors.emailInput, email);
|
||||
cy.clearAndType(onboardingSelectors.passwordInput, commonText.password);
|
||||
cy.get(commonSelectors.signUpButton).click();
|
||||
|
||||
cy.wait(500);
|
||||
|
|
@ -159,10 +149,9 @@ export const userSignUp = (fullName, email, workspaceName) => {
|
|||
}).then((resp) => {
|
||||
invitationLink = `/invitations/${resp.rows[0].invitation_token}`;
|
||||
cy.visit(invitationLink);
|
||||
cy.get(commonSelectors.setUpToolJetButton).click();
|
||||
cy.wait(4000);
|
||||
verifyOnboardingQuestions(fullName, workspaceName);
|
||||
updateWorkspaceName(email, workspaceName);
|
||||
cy.clearAndType('[data-cy="onboarding-workspace-name-input"]', workspaceName)
|
||||
cy.get('[data-cy="onboarding-submit-button"]').click();
|
||||
});
|
||||
};
|
||||
|
||||
|
|
@ -211,10 +200,10 @@ export const inviteUser = (firstName, email) => {
|
|||
cy.userInviteApi(firstName, email);
|
||||
fetchAndVisitInviteLink(email);
|
||||
cy.wait(1000);
|
||||
cy.get(commonSelectors.passwordInputField).should("be.visible");
|
||||
cy.clearAndType(commonSelectors.passwordInputField, "password");
|
||||
cy.get(onboardingSelectors.loginPasswordInput).should("be.visible");
|
||||
cy.clearAndType(onboardingSelectors.loginPasswordInput, "password");
|
||||
// cy.intercept("GET", "/api/organizations").as("org");
|
||||
cy.get(commonSelectors.signUpButton).click();
|
||||
cy.get(commonSelectors.continueButton).click();
|
||||
cy.wait(2000);
|
||||
cy.get(commonSelectors.acceptInviteButton).click();
|
||||
};
|
||||
|
|
@ -222,7 +211,7 @@ export const inviteUser = (firstName, email) => {
|
|||
export const addNewUser = (firstName, email) => {
|
||||
navigateToManageUsers();
|
||||
inviteUser(firstName, email);
|
||||
updateWorkspaceName(email);
|
||||
// updateWorkspaceName(email);
|
||||
};
|
||||
|
||||
export const updateWorkspaceName = (email, workspaceName = email) => {
|
||||
|
|
@ -300,19 +289,32 @@ export const visitWorkspaceInvitation = (email, workspaceName) => {
|
|||
|
||||
export const SignUpPageElements = () => {
|
||||
cy.get(commonSelectors.pageLogo).should("be.visible");
|
||||
cy.get(commonSelectors.SignUpSectionHeader).verifyVisibleElement(
|
||||
cy.get(commonSelectors.signUpSectionHeader).verifyVisibleElement(
|
||||
"have.text",
|
||||
"Sign up"
|
||||
);
|
||||
cy.get(commonSelectors.signUpButton).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.getStartedButton
|
||||
"Sign up"
|
||||
);
|
||||
cy.get(commonSelectors.signInRedirectText).should(($el) => {
|
||||
expect($el.contents().first().text().trim()).to.eq(
|
||||
commonText.signInRedirectText
|
||||
);
|
||||
});
|
||||
|
||||
// cy.get('[data-cy="signup-info"]').should(($el) => {
|
||||
// expect($el.contents().first().text().trim()).to.eq(
|
||||
// commonText.signInRedirectText
|
||||
// );
|
||||
// });
|
||||
|
||||
cy.get(onboardingSelectors.signupNameLabel).verifyVisibleElement("have.text", "Name *");
|
||||
cy.get(onboardingSelectors.nameInput).should('be.visible');
|
||||
cy.get(onboardingSelectors.emailLabel).verifyVisibleElement(
|
||||
"have.text",
|
||||
"Email *"
|
||||
);
|
||||
// cy.get(commonSelectors.loginPasswordLabel).verifyVisibleElement("have.text", "Password *");
|
||||
|
||||
cy.get(onboardingSelectors.loginPasswordInput).should("be.visible");
|
||||
|
||||
|
||||
cy.get(commonSelectors.signInRedirectLink).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.signInRedirectLink
|
||||
|
|
@ -357,5 +359,6 @@ export const signUpLink = (email) => {
|
|||
}).then((resp) => {
|
||||
invitationLink = `/invitations/${resp.rows[0].invitation_token}`;
|
||||
cy.visit(invitationLink);
|
||||
cy.wait(3000);
|
||||
});
|
||||
}
|
||||
|
|
@ -3,27 +3,27 @@ import { commonText } from "Texts/common";
|
|||
|
||||
export const selfHostCommonElements = () => {
|
||||
cy.get(commonSelectors.pageLogo).should("be.visible");
|
||||
cy.get(commonSelectors.setUpadminCheckPoint).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.setUpadminCheckPoint
|
||||
);
|
||||
// cy.get(commonSelectors.setUpadminCheckPoint).verifyVisibleElement(
|
||||
// "have.text",
|
||||
// commonText.setUpadminCheckPoint
|
||||
// );
|
||||
cy.get(commonSelectors.setUpworkspaceCheckPoint).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.setUpworkspaceCheckPoint
|
||||
);
|
||||
cy.get(commonSelectors.companyProfileCheckPoint).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.companyProfileCheckPoint
|
||||
);
|
||||
cy.get(commonSelectors.onboardingPageSubHeader).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.onboardingPageSubHeader
|
||||
);
|
||||
cy.get(commonSelectors.continueButton).verifyVisibleElement(
|
||||
// cy.get(commonSelectors.companyProfileCheckPoint).verifyVisibleElement(
|
||||
// "have.text",
|
||||
// commonText.companyProfileCheckPoint
|
||||
// );
|
||||
// cy.get(commonSelectors.onboardingPageSubHeader).verifyVisibleElement(
|
||||
// "have.text",
|
||||
// commonText.onboardingPageSubHeader
|
||||
// );
|
||||
cy.get(commonSelectors.OnbordingContinue).verifyVisibleElement(
|
||||
"have.text",
|
||||
commonText.continueButton
|
||||
);
|
||||
cy.get(commonSelectors.continueButton).should("be.disabled");
|
||||
// cy.get(commonSelectors.OnbordingContinue).should("be.disabled");
|
||||
};
|
||||
|
||||
export const commonElementsWorkspaceSetup = () => {
|
||||
|
|
|
|||
2444
cypress-tests/package-lock.json
generated
2444
cypress-tests/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -10,7 +10,7 @@
|
|||
"@cypress/code-coverage": "^3.12.12",
|
||||
"@cypress/webpack-preprocessor": "^5.12.0",
|
||||
"@faker-js/faker": "^7.3.0",
|
||||
"cypress": "^12.5.1"
|
||||
"cypress": "^13.16.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"cypress-real-events": "^1.7.6",
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
3.2.4-ce
|
||||
3.2.0-ce
|
||||
|
|
|
|||
9
frontend/assets/images/icons/ai-tag.svg
Normal file
9
frontend/assets/images/icons/ai-tag.svg
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<svg width="13" height="12" viewBox="0 0 13 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M2.26139 5.99998C5.20537 7.02317 6.17589 8.16244 6.89354 11C7.61119 8.16244 8.5817 7.02317 11.5257 5.99998C8.5817 4.97686 7.61119 3.83759 6.89354 1C6.17589 3.83759 5.20537 4.97686 2.26139 5.99998Z" fill="url(#paint0_linear_559_384)"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_559_384" x1="12.4652" y1="-5.5" x2="0.807046" y2="-4.34623" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FF5F6D"/>
|
||||
<stop offset="1" stop-color="#FFC371"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 575 B |
|
|
@ -279,6 +279,12 @@ export const QueryManagerBody = ({ darkMode, options, setOptions, activeTab }) =
|
|||
if (isEmpty(selectableDataSources)) {
|
||||
return '';
|
||||
}
|
||||
const isSampleDb = selectedDataSource?.type === DATA_SOURCE_TYPE.SAMPLE;
|
||||
const docLink = isSampleDb
|
||||
? 'https://docs.tooljet.com/docs/data-sources/sample-data-sources'
|
||||
: selectedDataSource?.pluginId && selectedDataSource.pluginId.trim() !== ''
|
||||
? `https://docs.tooljet.com/docs/marketplace/plugins/marketplace-plugin-${selectedDataSource?.kind}/`
|
||||
: `https://docs.tooljet.com/docs/data-sources/${selectedDataSource?.kind}`;
|
||||
return (
|
||||
<>
|
||||
<div className="" ref={paramListContainerRef}>
|
||||
|
|
@ -299,7 +305,7 @@ export const QueryManagerBody = ({ darkMode, options, setOptions, activeTab }) =
|
|||
>
|
||||
Source
|
||||
</div>
|
||||
<div className="d-flex align-items-end" style={{ width: '364px' }}>
|
||||
<div className="d-flex flex-column align-items-start" style={{ width: '500px' }}>
|
||||
<ChangeDataSource
|
||||
dataSources={selectableDataSources}
|
||||
value={selectedDataSource}
|
||||
|
|
@ -307,6 +313,18 @@ export const QueryManagerBody = ({ darkMode, options, setOptions, activeTab }) =
|
|||
changeDataQuery(newDataSource);
|
||||
}}
|
||||
/>
|
||||
<div>
|
||||
{`To know more about querying ${selectedDataSource?.kind} data,`}
|
||||
|
||||
<a
|
||||
href={docLink}
|
||||
target="_blank"
|
||||
style={{ marginLeft: '0px !important', color: 'hsl(226, 70.0%, 55.5%)', textDecoration: 'underline' }}
|
||||
rel="noreferrer"
|
||||
>
|
||||
{t('globals.readDocumentation', 'read documentation').toLowerCase()}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
|
|
|
|||
|
|
@ -3,12 +3,13 @@ import TabContent from './TabContent';
|
|||
|
||||
export default ({
|
||||
options = [],
|
||||
jsonBody,
|
||||
jsonBody, // FIXME: Remove this once data migration to raw_body is complete
|
||||
rawBody,
|
||||
theme,
|
||||
removeKeyValuePair,
|
||||
addNewKeyValuePair,
|
||||
onChange,
|
||||
onJsonBodyChange,
|
||||
onRawBodyChange,
|
||||
componentName,
|
||||
bodyToggle,
|
||||
}) => {
|
||||
|
|
@ -19,10 +20,11 @@ export default ({
|
|||
theme={theme}
|
||||
removeKeyValuePair={removeKeyValuePair}
|
||||
onChange={onChange}
|
||||
onJsonBodyChange={onJsonBodyChange}
|
||||
onRawBodyChange={onRawBodyChange}
|
||||
componentName={componentName}
|
||||
tabType={'body'}
|
||||
jsonBody={jsonBody}
|
||||
jsonBody={jsonBody} // FIXME: Remove this once data migration to raw_body is complete
|
||||
rawBody={rawBody}
|
||||
paramType={'body'}
|
||||
bodyToggle={bodyToggle}
|
||||
addNewKeyValuePair={addNewKeyValuePair}
|
||||
|
|
|
|||
|
|
@ -12,8 +12,9 @@ export default ({
|
|||
options = [],
|
||||
theme,
|
||||
onChange,
|
||||
jsonBody,
|
||||
onJsonBodyChange,
|
||||
jsonBody, // FIXME: Remove this once data migration to raw_body is complete
|
||||
rawBody,
|
||||
onRawBodyChange,
|
||||
componentName,
|
||||
removeKeyValuePair,
|
||||
paramType,
|
||||
|
|
@ -86,11 +87,10 @@ export default ({
|
|||
<div>
|
||||
<CodeHinter
|
||||
type="extendedSingleLine"
|
||||
initialValue={jsonBody ?? ''}
|
||||
lang="javascript"
|
||||
initialValue={(rawBody || jsonBody) ?? ''} // If raw_body is not set, set initial value to legacy json_body if present
|
||||
height={'300px'}
|
||||
className="query-hinter"
|
||||
onChange={(value) => onJsonBodyChange(value)}
|
||||
onChange={(value) => onRawBodyChange(value)}
|
||||
componentName={`${componentName}/${tabType}`}
|
||||
/>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ function ControlledTabs({
|
|||
options,
|
||||
theme,
|
||||
onChange,
|
||||
onJsonBodyChange,
|
||||
onRawBodyChange,
|
||||
removeKeyValuePair,
|
||||
addNewKeyValuePair,
|
||||
darkMode,
|
||||
|
|
@ -34,7 +34,7 @@ function ControlledTabs({
|
|||
</ListGroup>
|
||||
{key === 'body' && (
|
||||
<div className="text-nowrap d-flex align-items-center">
|
||||
Raw JSON
|
||||
Raw
|
||||
<CustomToggleSwitch
|
||||
toggleSwitchFunction={setBodyToggle}
|
||||
action="bodyToggle"
|
||||
|
|
@ -78,9 +78,10 @@ function ControlledTabs({
|
|||
removeKeyValuePair={removeKeyValuePair}
|
||||
addNewKeyValuePair={addNewKeyValuePair}
|
||||
onChange={onChange}
|
||||
onJsonBodyChange={onJsonBodyChange}
|
||||
onRawBodyChange={onRawBodyChange}
|
||||
options={options['body']}
|
||||
jsonBody={options['json_body']}
|
||||
jsonBody={options['json_body']} // FIXME: Remove this once data migration to raw_body is complete
|
||||
rawBody={options['raw_body']}
|
||||
theme={theme}
|
||||
bodyToggle={bodyToggle}
|
||||
darkMode={darkMode}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,15 @@ class Restapi extends React.Component {
|
|||
super(props);
|
||||
const options = defaults(
|
||||
{ ...props.options },
|
||||
{ headers: [['', '']], url_params: [], body: [], json_body: null, body_toggle: false, cookies: [['', '']] }
|
||||
{
|
||||
headers: [['', '']],
|
||||
url_params: [],
|
||||
body: [],
|
||||
json_body: null, // FIXME: Remove this once data migration to raw_body is complete
|
||||
raw_body: null,
|
||||
body_toggle: false,
|
||||
cookies: [['', '']],
|
||||
}
|
||||
);
|
||||
|
||||
this.state = {
|
||||
|
|
@ -117,9 +125,16 @@ class Restapi extends React.Component {
|
|||
});
|
||||
};
|
||||
|
||||
handleJsonBodyChanged = (jsonBody) => {
|
||||
handleRawBodyChanged = (rawBody) => {
|
||||
const { options } = deepClone(this.state);
|
||||
options['json_body'] = jsonBody;
|
||||
|
||||
// If this is the first time raw_body is set, nullify json_body for data migration
|
||||
// FIXME: Remove this if condition once data migration to raw_body is complete
|
||||
if (!options['raw_body'] && options['json_body']) {
|
||||
options['json_body'] = null;
|
||||
}
|
||||
|
||||
options['raw_body'] = rawBody;
|
||||
|
||||
this.setState({ options }, () => {
|
||||
this.props.optionsChanged(options);
|
||||
|
|
@ -188,7 +203,7 @@ class Restapi extends React.Component {
|
|||
</p>
|
||||
</div>
|
||||
<div className={`me-2`} style={{ width: '90px', height: '32px' }}>
|
||||
<label className="font-weight-medium color-slate12">Method</label>
|
||||
<label className="font-weight-bold color-slate12">Method</label>
|
||||
<Select
|
||||
options={[
|
||||
{ label: 'GET', value: 'get' },
|
||||
|
|
@ -211,7 +226,7 @@ class Restapi extends React.Component {
|
|||
</div>
|
||||
|
||||
<div className={`field w-100 rest-methods-url`}>
|
||||
<div className="font-weight-medium color-slate12">URL</div>
|
||||
<div className="font-weight-bold color-slate12">URL</div>
|
||||
<div className="d-flex">
|
||||
{dataSourceURL && (
|
||||
<BaseUrl theme={this.props.darkMode ? 'monokai' : 'default'} dataSourceURL={dataSourceURL} />
|
||||
|
|
@ -237,7 +252,7 @@ class Restapi extends React.Component {
|
|||
theme={this.props.darkMode ? 'monokai' : 'default'}
|
||||
options={this.state.options}
|
||||
onChange={this.handleChange}
|
||||
onJsonBodyChange={this.handleJsonBodyChanged}
|
||||
onRawBodyChange={this.handleRawBodyChanged}
|
||||
removeKeyValuePair={this.removeKeyValuePair}
|
||||
addNewKeyValuePair={this.addNewKeyValuePair}
|
||||
darkMode={this.props.darkMode}
|
||||
|
|
|
|||
|
|
@ -1,392 +0,0 @@
|
|||
import React from 'react';
|
||||
// import 'codemirror/theme/duotone-light.css';
|
||||
import DOMPurify from 'dompurify';
|
||||
import Select from '@/_ui/Select';
|
||||
import { openapiService } from '@/_services';
|
||||
import { withTranslation } from 'react-i18next';
|
||||
import { queryManagerSelectComponentStyle } from '@/_ui/Select/styles';
|
||||
import CodeHinter from '@/AppBuilder/CodeEditor';
|
||||
|
||||
const operationColorMapping = {
|
||||
get: 'azure',
|
||||
post: 'green',
|
||||
delete: 'red',
|
||||
put: 'yellow',
|
||||
};
|
||||
|
||||
class StripeComponent extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
loadingSpec: true,
|
||||
};
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
if (prevProps.options.parameters !== this.props.options.parameters) {
|
||||
this.setState({
|
||||
options: {
|
||||
...this.state.options,
|
||||
parameters: this.props.options.parameters,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const queryParams = {
|
||||
path: this.props.options?.params?.path ?? {},
|
||||
query: this.props.options?.params?.query ?? {},
|
||||
request: this.props.options?.params?.request ?? {},
|
||||
};
|
||||
this.setState({
|
||||
loadingSpec: true,
|
||||
options: {
|
||||
...this.props.options,
|
||||
params: queryParams,
|
||||
},
|
||||
});
|
||||
|
||||
this.fetchOpenApiSpec();
|
||||
}
|
||||
|
||||
fetchOpenApiSpec = () => {
|
||||
this.setState({ loadingSpec: true });
|
||||
|
||||
openapiService
|
||||
.fetchSpecFromUrl('https://raw.githubusercontent.com/stripe/openapi/master/openapi/spec3.json')
|
||||
.then((response) => {
|
||||
response.text().then((text) => {
|
||||
const data = JSON.parse(text);
|
||||
this.setState({ specJson: data, loadingSpec: false });
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
changeOption(option, value) {
|
||||
this.setState({
|
||||
options: {
|
||||
...this.state.options,
|
||||
[option]: value,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
changeOperation = (value) => {
|
||||
const operation = value.split(',')[0];
|
||||
const path = value.split(',')[1];
|
||||
|
||||
this.setState(
|
||||
{
|
||||
options: {
|
||||
...this.state.options,
|
||||
path,
|
||||
operation,
|
||||
selectedOperation: this.state.specJson.paths[path][operation],
|
||||
},
|
||||
},
|
||||
() => {
|
||||
this.props.optionsChanged(this.state.options);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
changeParam = (paramType, paramName, value) => {
|
||||
const options = this.state.options;
|
||||
const newOptions = {
|
||||
...options,
|
||||
params: {
|
||||
...options.params,
|
||||
[paramType]: {
|
||||
...options.params[paramType],
|
||||
[paramName]: value,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
this.setState({
|
||||
options: newOptions,
|
||||
});
|
||||
|
||||
this.props.optionsChanged(newOptions);
|
||||
};
|
||||
|
||||
removeParam = (paramType, paramName) => {
|
||||
const newOptions = JSON.parse(JSON.stringify(this.state.options));
|
||||
newOptions['params'][paramType][paramName] = undefined;
|
||||
|
||||
this.setState(
|
||||
{
|
||||
options: newOptions,
|
||||
},
|
||||
() => {
|
||||
this.props.optionsChanged(newOptions);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
renderOperationOption = (props) => {
|
||||
const path = props.value;
|
||||
const operation = props.label;
|
||||
if (path && operation) {
|
||||
return (
|
||||
<div className="row">
|
||||
<div className="col-auto" style={{ width: '60px' }}>
|
||||
<span className={`badge bg-${operationColorMapping[operation]}`}>{operation}</span>
|
||||
</div>
|
||||
|
||||
<div className="col">
|
||||
<span>{path}</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
return 'Select an operation';
|
||||
}
|
||||
};
|
||||
|
||||
computeOperationSelectionOptions = (operationOptions) => {
|
||||
let options = [];
|
||||
const paths = operationOptions?.paths;
|
||||
|
||||
if (paths) {
|
||||
for (const path of Object.keys(paths)) {
|
||||
for (const operation of Object.keys(paths[path])) {
|
||||
options.push({
|
||||
value: `${operation},${path}`,
|
||||
name: path,
|
||||
operation: operation,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return options;
|
||||
};
|
||||
|
||||
render() {
|
||||
const { options, specJson, loadingSpec } = this.state;
|
||||
const selectedOperation = options?.selectedOperation;
|
||||
|
||||
let pathParams = [];
|
||||
let queryParams = [];
|
||||
let requestBody = [];
|
||||
|
||||
if (selectedOperation) {
|
||||
if (selectedOperation.parameters) {
|
||||
pathParams = selectedOperation.parameters.filter((param) => param.in === 'path');
|
||||
queryParams = selectedOperation.parameters.filter((param) => param.in === 'query');
|
||||
}
|
||||
|
||||
if (selectedOperation.requestBody) {
|
||||
const requestType = Object.keys(selectedOperation.requestBody.content)[0];
|
||||
requestBody = selectedOperation.requestBody.content[requestType];
|
||||
}
|
||||
}
|
||||
|
||||
const currentValue = this.state.options?.operation + ',' + this.props.options?.path ?? null;
|
||||
|
||||
return (
|
||||
<div>
|
||||
{loadingSpec && (
|
||||
<div className="p-3">
|
||||
<div className="spinner-border spinner-border-sm text-azure mx-2" role="status"></div>
|
||||
{this.props.t('stripe', 'Please wait while we load the OpenAPI specification for Stripe.')}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{options && !loadingSpec && (
|
||||
<div>
|
||||
<div className="d-flex stripe-operation-container g-2">
|
||||
<div className="col-12 form-label">
|
||||
<label className="form-label">{this.props.t('globals.operation', 'Operation')}</label>
|
||||
</div>
|
||||
<div className="col stripe-operation-options flex-grow-1" style={{ width: '90px', marginTop: 0 }}>
|
||||
<Select
|
||||
options={this.computeOperationSelectionOptions(specJson)}
|
||||
value={currentValue}
|
||||
onChange={(value) => this.changeOperation(value)}
|
||||
width={'100%'}
|
||||
useMenuPortal={true}
|
||||
customOption={this.renderOperationOption}
|
||||
styles={queryManagerSelectComponentStyle(this.props.darkMode, '100%')}
|
||||
useCustomStyles={true}
|
||||
/>
|
||||
|
||||
{selectedOperation && (
|
||||
<small
|
||||
style={{ margintTop: '10px' }}
|
||||
className="my-2"
|
||||
dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(selectedOperation.description) }}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{selectedOperation && (
|
||||
<div className={`row stripe-fields-row ${this.props.darkMode && 'theme-dark'}`}>
|
||||
{pathParams.length > 0 && (
|
||||
<div className={`path-fields ${Object.keys(requestBody.schema.properties).length === 0 && 'd-none'}`}>
|
||||
<h5 className="text-heading">{this.props.t('globals.path', 'PATH')}</h5>
|
||||
<div className="input-group-parent-container">
|
||||
{pathParams.map((param) => (
|
||||
<div className="input-group-wrapper" key={param.name}>
|
||||
<div className="input-group">
|
||||
<div className="col-auto field field-width-179">
|
||||
<input
|
||||
type="text"
|
||||
value={param.name}
|
||||
className="form-control border-0"
|
||||
placeholder="key"
|
||||
/>
|
||||
</div>
|
||||
<div className="col field overflow-hidden">
|
||||
<CodeHinter
|
||||
type="basic"
|
||||
initialValue={this.state.options.params.path[param.name]}
|
||||
placeholder={'Value'}
|
||||
onChange={(value) => this.changeParam('path', param.name, value)}
|
||||
/>
|
||||
</div>
|
||||
<span
|
||||
className="col-auto field-width-28 d-flex"
|
||||
role="button"
|
||||
onClick={() => this.removeParam('path', param.name)}
|
||||
>
|
||||
<svg
|
||||
width="100%"
|
||||
height="100%"
|
||||
viewBox="0 0 12 13"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M5.99931 6.97508L11.0242 12.0014L12 11.027L6.9737 6.00069L12 0.975767L11.0256 0L5.99931 5.0263L0.974388 0L0 0.975767L5.02492 6.00069L0 11.0256L0.974388 12.0014L5.99931 6.97508Z"
|
||||
fill="#11181C"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{queryParams.length > 0 && (
|
||||
<div
|
||||
className={`query-fields ${Object.keys(requestBody.schema.properties).length === 0 && 'd-none'}`}
|
||||
>
|
||||
<h5 className="text-heading">{this.props.t('globals.query'.toUpperCase(), 'QUERY')}</h5>
|
||||
<div className="input-group-parent-container">
|
||||
{queryParams.map((param) => (
|
||||
<div className="input-group-wrapper" key={param.name}>
|
||||
<div className="input-group">
|
||||
<div className="col-auto field field-width-179">
|
||||
<input
|
||||
type="text"
|
||||
value={param.name}
|
||||
className="form-control"
|
||||
placeholder="key"
|
||||
disabled
|
||||
/>
|
||||
</div>
|
||||
<div className="col field overflow-hidden">
|
||||
<CodeHinter
|
||||
type="basic"
|
||||
initialValue={this.state.options.params?.query[param.name] ?? ''}
|
||||
placeholder={'Value'}
|
||||
onChange={(value) => this.changeParam('query', param.name, value)}
|
||||
/>
|
||||
</div>
|
||||
<span
|
||||
className="col-auto field-width-28 d-flex"
|
||||
role="button"
|
||||
onClick={() => this.removeParam('query', param.name)}
|
||||
>
|
||||
<svg
|
||||
width="100%"
|
||||
height="100%"
|
||||
viewBox="0 0 12 13"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M5.99931 6.97508L11.0242 12.0014L12 11.027L6.9737 6.00069L12 0.975767L11.0256 0L5.99931 5.0263L0.974388 0L0 0.975767L5.02492 6.00069L0 11.0256L0.974388 12.0014L5.99931 6.97508Z"
|
||||
fill="#11181C"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{requestBody.schema.properties && (
|
||||
<div
|
||||
className={`request-body-fields d-flex ${
|
||||
Object.keys(requestBody.schema.properties).length === 0 && 'd-none'
|
||||
} `}
|
||||
>
|
||||
<h5 className="text-heading form-label">{this.props.t('globals.requestBody', 'REQUEST BODY')}</h5>
|
||||
<div
|
||||
className={`flex-grow-1 ${
|
||||
Object.keys(requestBody.schema.properties).length >= 1 && 'input-group-parent-container'
|
||||
}`}
|
||||
>
|
||||
{Object.keys(requestBody.schema.properties).map((param) => (
|
||||
<div className="input-group-wrapper" key={param.name}>
|
||||
<div className="input-group">
|
||||
<div className="col-auto field field-width-179">
|
||||
<input type="text" value={param} className="form-control" placeholder="key" disabled />
|
||||
</div>
|
||||
<div className="col field overflow-hidden">
|
||||
<CodeHinter
|
||||
type="basic"
|
||||
initialValue={this.state.options.params?.request[param] ?? ''}
|
||||
placeholder={'Value'}
|
||||
onChange={(value) => this.changeParam('request', param, value)}
|
||||
/>
|
||||
</div>
|
||||
<span
|
||||
className="col-auto field-width-28 d-flex"
|
||||
role="button"
|
||||
onClick={() => this.removeParam('request', param)}
|
||||
>
|
||||
<svg
|
||||
width="100%"
|
||||
height="100%"
|
||||
viewBox="0 0 12 13"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M5.99931 6.97508L11.0242 12.0014L12 11.027L6.9737 6.00069L12 0.975767L11.0256 0L5.99931 5.0263L0.974388 0L0 0.975767L5.02492 6.00069L0 11.0256L0.974388 12.0014L5.99931 6.97508Z"
|
||||
fill="#11181C"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export const Stripe = withTranslation()(StripeComponent);
|
||||
|
|
@ -6,7 +6,6 @@ import { Restapi } from './Restapi';
|
|||
// eslint-disable-next-line import/no-unresolved
|
||||
import { Runjs } from './Runjs';
|
||||
import { Runpy } from './Runpy';
|
||||
import { Stripe } from './Stripe';
|
||||
import { Openapi } from './Openapi';
|
||||
import { Workflows } from './Workflows';
|
||||
import Grpc from './GRPC';
|
||||
|
|
@ -37,7 +36,6 @@ export const allSources = {
|
|||
Restapi,
|
||||
Runjs,
|
||||
Runpy,
|
||||
Stripe,
|
||||
Openapi,
|
||||
Grpc,
|
||||
Workflows,
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ export const Container = ({
|
|||
|
||||
return (
|
||||
<div
|
||||
className={`jet-container tw-flex tw-flex-col ${properties.loadingState && 'jet-container-loading'} ${
|
||||
className={`jet-container tw-flex tw-flex-col ${isLoading ? 'jet-container-loading' : ''} ${
|
||||
properties.showHeader && 'jet-container--with-header'
|
||||
}`}
|
||||
id={id}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ import { withRouter } from '@/_hoc/withRouter';
|
|||
import { DATA_SOURCE_TYPE } from '@/_helpers/constants';
|
||||
import './dataSourceManager.theme.scss';
|
||||
import { useAppVersionStore } from '@/_stores/appVersionStore';
|
||||
|
||||
import { canUpdateDataSource } from '@/_helpers';
|
||||
class DataSourceManagerComponent extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
@ -807,67 +807,86 @@ class DataSourceManagerComponent extends React.Component {
|
|||
{...this.props.modalProps}
|
||||
>
|
||||
<Modal.Header className={'d-block'}>
|
||||
<div className="d-flex">
|
||||
{selectedDataSource && this.props.showBackButton && (
|
||||
<div
|
||||
className={`back-btn me-3 mt-3 ${this.props.darkMode ? 'dark' : ''}`}
|
||||
role="button"
|
||||
onClick={() => this.setState({ selectedDataSource: false }, () => this.onExit())}
|
||||
>
|
||||
<img
|
||||
data-cy="button-back-ds-connection-modal"
|
||||
className="m-0"
|
||||
src="assets/images/icons/back.svg"
|
||||
width="30"
|
||||
height="30"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<Modal.Title className="mt-3">
|
||||
{selectedDataSource && !isSampleDb ? (
|
||||
<div className="row selected-ds">
|
||||
{getSvgIcon(dataSourceMeta?.kind?.toLowerCase(), 35, 35, selectedDataSourceIcon)}
|
||||
<div className="input-icon" style={{ width: '160px' }}>
|
||||
<input
|
||||
type="text"
|
||||
onChange={(e) => this.onNameChanged(e.target.value)}
|
||||
className="form-control-plaintext form-control-plaintext-sm color-slate12"
|
||||
value={decodeEntities(selectedDataSource.name)}
|
||||
style={{ width: '160px' }}
|
||||
data-cy="data-source-name-input-filed"
|
||||
autoFocus
|
||||
autoComplete="off"
|
||||
/>
|
||||
{!this.props.isEditing && (
|
||||
<span className="input-icon-addon">
|
||||
<img src="assets/images/icons/edit-source.svg" width="12" height="12" />
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div className="row">
|
||||
<div className="col-md-2">
|
||||
<SolidIcon name="tooljet" />
|
||||
</div>
|
||||
<div className="col-md-10"> Sample data source</div>
|
||||
<div className="d-flex align-items-center justify-content-between">
|
||||
<div className="d-flex">
|
||||
{selectedDataSource && this.props.showBackButton && (
|
||||
<div
|
||||
className={`back-btn me-3 mt-3 ${this.props.darkMode ? 'dark' : ''}`}
|
||||
role="button"
|
||||
onClick={() => this.setState({ selectedDataSource: false }, () => this.onExit())}
|
||||
>
|
||||
<img
|
||||
data-cy="button-back-ds-connection-modal"
|
||||
className="m-0"
|
||||
src="assets/images/icons/back.svg"
|
||||
width="30"
|
||||
height="30"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{!selectedDataSource && (
|
||||
<span className="" data-cy="title-add-new-datasource">
|
||||
{this.props.t('editor.queryManager.dataSourceManager.addNewDataSource', 'Add new datasource')}
|
||||
<Modal.Title className="mt-3">
|
||||
{selectedDataSource && !isSampleDb ? (
|
||||
<div className="row selected-ds">
|
||||
{getSvgIcon(dataSourceMeta?.kind?.toLowerCase(), 35, 35, selectedDataSourceIcon)}
|
||||
<div className="input-icon" style={{ width: '160px' }}>
|
||||
<input
|
||||
type="text"
|
||||
onChange={(e) => this.onNameChanged(e.target.value)}
|
||||
className="form-control-plaintext form-control-plaintext-sm color-slate12"
|
||||
value={decodeEntities(selectedDataSource.name)}
|
||||
style={{ width: '160px' }}
|
||||
data-cy="data-source-name-input-filed"
|
||||
autoFocus
|
||||
autoComplete="off"
|
||||
disabled={!canUpdateDataSource(selectedDataSource.id)}
|
||||
/>
|
||||
{!this.props.isEditing && (
|
||||
<span className="input-icon-addon">
|
||||
<img src="assets/images/icons/edit-source.svg" width="12" height="12" />
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div className="row">
|
||||
<div className="col-md-2">
|
||||
<SolidIcon name="tooljet" />
|
||||
</div>
|
||||
<div className="col-md-10" data-cy="sample-data-source-title">
|
||||
{' '}
|
||||
Sample data source
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{!selectedDataSource && (
|
||||
<span className="" data-cy="title-add-new-datasource">
|
||||
{this.props.t('editor.queryManager.dataSourceManager.addNewDataSource', 'Add new datasource')}
|
||||
</span>
|
||||
)}
|
||||
</Modal.Title>
|
||||
{!this.props.isEditing && (
|
||||
<span
|
||||
data-cy="button-close-ds-connection-modal"
|
||||
className={`close-btn mx-4 mt-3 ${this.props.darkMode ? 'dark' : ''}`}
|
||||
onClick={() => this.hideModal()}
|
||||
>
|
||||
<SolidIcon name="remove" width="20" fill={'var(--slate12)'} />
|
||||
</span>
|
||||
)}
|
||||
</Modal.Title>
|
||||
{!this.props.isEditing && (
|
||||
<span
|
||||
data-cy="button-close-ds-connection-modal"
|
||||
className={`close-btn mx-4 mt-3 ${this.props.darkMode ? 'dark' : ''}`}
|
||||
onClick={() => this.hideModal()}
|
||||
>
|
||||
<SolidIcon name="remove" width="20" fill={'var(--slate12)'} />
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<div className="tw-pt-[15px]">
|
||||
{this.props.tags &&
|
||||
this.props.tags.map((tag) => {
|
||||
if (tag === 'AI') {
|
||||
return (
|
||||
<div key={tag} className="tag-container">
|
||||
<SolidIcon name="AI-tag" />
|
||||
<span>{tag}</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
{this.renderEnvironmentsTab(selectedDataSource)}
|
||||
</Modal.Header>
|
||||
|
|
|
|||
|
|
@ -12,7 +12,12 @@ import { ChangeDataSource } from './ChangeDataSource';
|
|||
import { CustomToggleSwitch } from './CustomToggleSwitch';
|
||||
import { EventManager } from '@/Editor/Inspector/EventManager';
|
||||
import { staticDataSources, customToggles, mockDataQueryAsComponent, RestAPIToggles } from '../constants';
|
||||
import { DataSourceTypes } from '../../DataSourceManager/SourceComponents';
|
||||
import {
|
||||
DataSourceTypes,
|
||||
DataBaseSources,
|
||||
ApiSources,
|
||||
CloudStorageSources,
|
||||
} from '../../DataSourceManager/SourceComponents';
|
||||
import { useDataSources, useGlobalDataSources, useSampleDataSource } from '@/_stores/dataSourcesStore';
|
||||
import { useDataQueriesActions } from '@/_stores/dataQueriesStore';
|
||||
import { useSelectedQuery, useSelectedDataSource } from '@/_stores/queryPanelStore';
|
||||
|
|
@ -21,6 +26,7 @@ import { shallow } from 'zustand/shallow';
|
|||
import SuccessNotificationInputs from './SuccessNotificationInputs';
|
||||
import ParameterList from './ParameterList';
|
||||
import { deepClone } from '@/_helpers/utilities/utils.helpers';
|
||||
import { DATA_SOURCE_TYPE } from '@/_helpers/constants';
|
||||
|
||||
export const QueryManagerBody = ({
|
||||
darkMode,
|
||||
|
|
@ -49,6 +55,10 @@ export const QueryManagerBody = ({
|
|||
- Ref PR #6763
|
||||
*/
|
||||
const [selectedQueryId, setSelectedQueryId] = useState(selectedQuery?.id);
|
||||
const [dataSourcesKinds, setDataSourcesKinds] = useState([]);
|
||||
const [userDefinedSources, setUserDefinedSources] = useState(
|
||||
[...dataSources, ...globalDataSources, !!sampleDataSource && sampleDataSource].filter(Boolean)
|
||||
);
|
||||
|
||||
const queryName = selectedQuery?.name ?? '';
|
||||
const sourcecomponentName = selectedDataSource?.kind?.charAt(0).toUpperCase() + selectedDataSource?.kind?.slice(1);
|
||||
|
|
@ -64,6 +74,24 @@ export const QueryManagerBody = ({
|
|||
shallow
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
const shouldAddSampleDataSource = !!sampleDataSource;
|
||||
const allDataSources = [...dataSources, ...globalDataSources, shouldAddSampleDataSource && sampleDataSource].filter(
|
||||
Boolean
|
||||
);
|
||||
setUserDefinedSources(allDataSources);
|
||||
const dataSourceKindsList = [...DataBaseSources, ...ApiSources, ...CloudStorageSources];
|
||||
allDataSources.forEach(({ plugin }) => {
|
||||
//plugin names are fetched from list data source api call only
|
||||
if (isEmpty(plugin)) {
|
||||
return;
|
||||
}
|
||||
dataSourceKindsList.push({ name: plugin.name, kind: plugin.pluginId });
|
||||
});
|
||||
setDataSourcesKinds(dataSourceKindsList);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [dataSources]);
|
||||
|
||||
useEffect(() => {
|
||||
setDataSourceMeta(
|
||||
selectedQuery?.pluginId
|
||||
|
|
@ -308,6 +336,14 @@ export const QueryManagerBody = ({
|
|||
if (isEmpty(selectableDataSources)) {
|
||||
return '';
|
||||
}
|
||||
const isSampleDb = selectedDataSource?.type === DATA_SOURCE_TYPE.SAMPLE;
|
||||
const docLink = isSampleDb
|
||||
? 'https://docs.tooljet.com/docs/data-sources/sample-data-sources'
|
||||
: selectedDataSource?.pluginId && selectedDataSource.pluginId.trim() !== ''
|
||||
? `https://docs.tooljet.com/docs/marketplace/plugins/marketplace-plugin-${selectedDataSource?.kind}/`
|
||||
: `https://docs.tooljet.com/docs/data-sources/${selectedDataSource?.kind}`;
|
||||
const selectedDataSourceName =
|
||||
dataSourcesKinds.find((dsk) => dsk.kind === selectedDataSource.kind)?.name || selectedDataSource.kind;
|
||||
return (
|
||||
<>
|
||||
<div className="" ref={paramListContainerRef}>
|
||||
|
|
@ -329,10 +365,11 @@ export const QueryManagerBody = ({
|
|||
>
|
||||
<div
|
||||
className={`d-flex query-manager-border-color hr-text-left py-2 form-label font-weight-500 change-data-source`}
|
||||
style={{ minWidth: '140px' }}
|
||||
>
|
||||
Source
|
||||
</div>
|
||||
<div className="d-flex align-items-end" style={{ width: '364px' }}>
|
||||
<div className="d-flex flex-column align-items-start" style={{ width: '100%' }}>
|
||||
<ChangeDataSource
|
||||
dataSources={selectableDataSources}
|
||||
value={selectedDataSource}
|
||||
|
|
@ -340,6 +377,18 @@ export const QueryManagerBody = ({
|
|||
changeDataQuery(newDataSource);
|
||||
}}
|
||||
/>
|
||||
<div>
|
||||
{`To know more about querying ${selectedDataSourceName} data,`}
|
||||
|
||||
<a
|
||||
href={docLink}
|
||||
target="_blank"
|
||||
style={{ marginLeft: '0px !important', color: 'hsl(226, 70.0%, 55.5%)', textDecoration: 'underline' }}
|
||||
rel="noreferrer"
|
||||
>
|
||||
{t('globals.readDocumentation', 'read documentation').toLowerCase()}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
|
|
|
|||
|
|
@ -3,12 +3,13 @@ import TabContent from './TabContent';
|
|||
|
||||
export default ({
|
||||
options = [],
|
||||
jsonBody,
|
||||
jsonBody, // FIXME: Remove this once data migration to raw_body is complete
|
||||
rawBody,
|
||||
theme,
|
||||
removeKeyValuePair,
|
||||
addNewKeyValuePair,
|
||||
onChange,
|
||||
onJsonBodyChange,
|
||||
onRawBodyChange,
|
||||
componentName,
|
||||
bodyToggle,
|
||||
}) => {
|
||||
|
|
@ -19,10 +20,11 @@ export default ({
|
|||
theme={theme}
|
||||
removeKeyValuePair={removeKeyValuePair}
|
||||
onChange={onChange}
|
||||
onJsonBodyChange={onJsonBodyChange}
|
||||
onRawBodyChange={onRawBodyChange}
|
||||
componentName={componentName}
|
||||
tabType={'body'}
|
||||
jsonBody={jsonBody}
|
||||
jsonBody={jsonBody} // FIXME: Remove this once data migration to raw_body is complete
|
||||
rawBody={rawBody}
|
||||
paramType={'body'}
|
||||
bodyToggle={bodyToggle}
|
||||
addNewKeyValuePair={addNewKeyValuePair}
|
||||
|
|
|
|||
|
|
@ -10,8 +10,9 @@ export default ({
|
|||
options = [],
|
||||
theme,
|
||||
onChange,
|
||||
jsonBody,
|
||||
onJsonBodyChange,
|
||||
jsonBody, // FIXME: Remove this once data migration to raw_body is complete
|
||||
rawBody,
|
||||
onRawBodyChange,
|
||||
componentName,
|
||||
removeKeyValuePair,
|
||||
paramType,
|
||||
|
|
@ -74,11 +75,10 @@ export default ({
|
|||
<div>
|
||||
<CodeHinter
|
||||
type="extendedSingleLine"
|
||||
initialValue={jsonBody ?? ''}
|
||||
lang="javascript"
|
||||
initialValue={(rawBody || jsonBody) ?? ''} // If raw_body is not set, set initial value to legacy json_body if present
|
||||
height={'300px'}
|
||||
className="query-hinter"
|
||||
onChange={(value) => onJsonBodyChange(value)}
|
||||
onChange={(value) => onRawBodyChange(value)}
|
||||
componentName={`${componentName}/${tabType}`}
|
||||
/>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ function ControlledTabs({
|
|||
options,
|
||||
theme,
|
||||
onChange,
|
||||
onJsonBodyChange,
|
||||
onRawBodyChange,
|
||||
removeKeyValuePair,
|
||||
addNewKeyValuePair,
|
||||
darkMode,
|
||||
|
|
@ -34,7 +34,7 @@ function ControlledTabs({
|
|||
</ListGroup>
|
||||
{key === 'body' && (
|
||||
<div className="text-nowrap d-flex align-items-center">
|
||||
Raw JSON
|
||||
Raw
|
||||
<CustomToggleSwitch
|
||||
toggleSwitchFunction={setBodyToggle}
|
||||
action="bodyToggle"
|
||||
|
|
@ -78,9 +78,10 @@ function ControlledTabs({
|
|||
removeKeyValuePair={removeKeyValuePair}
|
||||
addNewKeyValuePair={addNewKeyValuePair}
|
||||
onChange={onChange}
|
||||
onJsonBodyChange={onJsonBodyChange}
|
||||
onRawBodyChange={onRawBodyChange}
|
||||
options={options['body']}
|
||||
jsonBody={options['json_body']}
|
||||
jsonBody={options['json_body']} // FIXME: Remove this once data migration to raw_body is complete
|
||||
rawBody={options['raw_body']}
|
||||
theme={theme}
|
||||
bodyToggle={bodyToggle}
|
||||
darkMode={darkMode}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,15 @@ class Restapi extends React.Component {
|
|||
super(props);
|
||||
const options = defaults(
|
||||
{ ...props.options },
|
||||
{ headers: [['', '']], url_params: [], body: [], json_body: null, body_toggle: false, cookies: [['', '']] }
|
||||
{
|
||||
headers: [['', '']],
|
||||
url_params: [],
|
||||
body: [],
|
||||
json_body: null, // FIXME: Remove this once data migration to raw_body is complete
|
||||
raw_body: null,
|
||||
body_toggle: false,
|
||||
cookies: [['', '']],
|
||||
}
|
||||
);
|
||||
this.state = {
|
||||
options,
|
||||
|
|
@ -105,9 +113,16 @@ class Restapi extends React.Component {
|
|||
});
|
||||
};
|
||||
|
||||
handleJsonBodyChanged = (jsonBody) => {
|
||||
handleRawBodyChanged = (rawBody) => {
|
||||
const { options } = this.state;
|
||||
options['json_body'] = jsonBody;
|
||||
|
||||
// If this is the first time raw_body is set, nullify json_body for data migration
|
||||
// FIXME: Remove this if condition once data migration to raw_body is complete
|
||||
if (!options['raw_body'] && options['json_body']) {
|
||||
options['json_body'] = null;
|
||||
}
|
||||
|
||||
options['raw_body'] = rawBody;
|
||||
|
||||
this.setState({ options }, () => {
|
||||
this.props.optionsChanged(options);
|
||||
|
|
@ -163,12 +178,12 @@ class Restapi extends React.Component {
|
|||
|
||||
const currentValue = { label: options.method?.toUpperCase(), value: options.method };
|
||||
return (
|
||||
<div className={`d-flex flex-column`}>
|
||||
{this.props.selectedDataSource?.scope == 'global' && <div className="form-label flex-shrink-0"></div>}{' '}
|
||||
<div className="flex-grow-1 overflow-hidden">
|
||||
<div className={`${this.props?.queryName !== 'workflowNode' && 'd-flex'}`}>
|
||||
{this.props?.queryName !== 'workflowNode' && <div className="form-label flex-shrink-0">Request</div>}
|
||||
<div className="flex-grow-1">
|
||||
<div className="rest-api-methods-select-element-container">
|
||||
<div className={`me-2`} style={{ width: '90px', height: '32px' }}>
|
||||
<label className="font-weight-medium color-slate12">Method</label>
|
||||
<label className="font-weight-bold color-slate12">Method</label>
|
||||
<Select
|
||||
options={[
|
||||
{ label: 'GET', value: 'get' },
|
||||
|
|
@ -191,12 +206,15 @@ class Restapi extends React.Component {
|
|||
</div>
|
||||
|
||||
<div className={`field w-100 rest-methods-url`}>
|
||||
<div className="font-weight-medium color-slate12">URL</div>
|
||||
<div className="font-weight-bold color-slate12">URL</div>
|
||||
<div className="d-flex">
|
||||
{dataSourceURL && (
|
||||
<BaseUrl theme={this.props.darkMode ? 'monokai' : 'default'} dataSourceURL={dataSourceURL} />
|
||||
)}
|
||||
<div className={`flex-grow-1 ${dataSourceURL ? 'url-input-group' : ''}`}>
|
||||
<div
|
||||
className={`flex-grow-1 rest-api-url-codehinter ${dataSourceURL ? 'url-input-group' : ''}`}
|
||||
style={{ width: '530px' }}
|
||||
>
|
||||
<CodeHinter
|
||||
type="basic"
|
||||
initialValue={options.url}
|
||||
|
|
@ -211,20 +229,20 @@ class Restapi extends React.Component {
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className={`query-pane-restapi-tabs`}>
|
||||
<Tabs
|
||||
theme={this.props.darkMode ? 'monokai' : 'default'}
|
||||
options={this.state.options}
|
||||
onChange={this.handleChange}
|
||||
onJsonBodyChange={this.handleJsonBodyChanged}
|
||||
removeKeyValuePair={this.removeKeyValuePair}
|
||||
addNewKeyValuePair={this.addNewKeyValuePair}
|
||||
darkMode={this.props.darkMode}
|
||||
componentName={queryName}
|
||||
bodyToggle={this.state.options.body_toggle}
|
||||
setBodyToggle={this.onBodyToggleChanged}
|
||||
/>
|
||||
<div className={`query-pane-restapi-tabs`}>
|
||||
<Tabs
|
||||
theme={this.props.darkMode ? 'monokai' : 'default'}
|
||||
options={this.state.options}
|
||||
onChange={this.handleChange}
|
||||
onRawBodyChange={this.handleRawBodyChanged}
|
||||
removeKeyValuePair={this.removeKeyValuePair}
|
||||
addNewKeyValuePair={this.addNewKeyValuePair}
|
||||
darkMode={this.props.darkMode}
|
||||
componentName={queryName}
|
||||
bodyToggle={this.state.options.body_toggle}
|
||||
setBodyToggle={this.onBodyToggleChanged}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,381 +0,0 @@
|
|||
import React from 'react';
|
||||
// import 'codemirror/theme/duotone-light.css';
|
||||
import DOMPurify from 'dompurify';
|
||||
import Select from '@/_ui/Select';
|
||||
import { openapiService } from '@/_services';
|
||||
import { withTranslation } from 'react-i18next';
|
||||
import { queryManagerSelectComponentStyle } from '@/_ui/Select/styles';
|
||||
import CodeHinter from '@/Editor/CodeEditor';
|
||||
|
||||
const operationColorMapping = {
|
||||
get: 'azure',
|
||||
post: 'green',
|
||||
delete: 'red',
|
||||
put: 'yellow',
|
||||
};
|
||||
|
||||
class StripeComponent extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
loadingSpec: true,
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const queryParams = {
|
||||
path: this.props.options?.params?.path ?? {},
|
||||
query: this.props.options?.params?.query ?? {},
|
||||
request: this.props.options?.params?.request ?? {},
|
||||
};
|
||||
this.setState({
|
||||
loadingSpec: true,
|
||||
options: {
|
||||
...this.props.options,
|
||||
params: queryParams,
|
||||
},
|
||||
});
|
||||
|
||||
this.fetchOpenApiSpec();
|
||||
}
|
||||
|
||||
fetchOpenApiSpec = () => {
|
||||
this.setState({ loadingSpec: true });
|
||||
|
||||
openapiService
|
||||
.fetchSpecFromUrl('https://raw.githubusercontent.com/stripe/openapi/master/openapi/spec3.json')
|
||||
.then((response) => {
|
||||
response.text().then((text) => {
|
||||
const data = JSON.parse(text);
|
||||
this.setState({ specJson: data, loadingSpec: false });
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
changeOption(option, value) {
|
||||
this.setState({
|
||||
options: {
|
||||
...this.state.options,
|
||||
[option]: value,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
changeOperation = (value) => {
|
||||
const operation = value.split(',')[0];
|
||||
const path = value.split(',')[1];
|
||||
|
||||
this.setState(
|
||||
{
|
||||
options: {
|
||||
...this.state.options,
|
||||
path,
|
||||
operation,
|
||||
selectedOperation: this.state.specJson.paths[path][operation],
|
||||
},
|
||||
},
|
||||
() => {
|
||||
this.props.optionsChanged(this.state.options);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
changeParam = (paramType, paramName, value) => {
|
||||
const options = this.state.options;
|
||||
const newOptions = {
|
||||
...options,
|
||||
params: {
|
||||
...options.params,
|
||||
[paramType]: {
|
||||
...options.params[paramType],
|
||||
[paramName]: value,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
this.setState({
|
||||
options: newOptions,
|
||||
});
|
||||
|
||||
this.props.optionsChanged(newOptions);
|
||||
};
|
||||
|
||||
removeParam = (paramType, paramName) => {
|
||||
const newOptions = JSON.parse(JSON.stringify(this.state.options));
|
||||
newOptions['params'][paramType][paramName] = undefined;
|
||||
|
||||
this.setState(
|
||||
{
|
||||
options: newOptions,
|
||||
},
|
||||
() => {
|
||||
this.props.optionsChanged(newOptions);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
renderOperationOption = (props) => {
|
||||
const path = props.value;
|
||||
const operation = props.label;
|
||||
if (path && operation) {
|
||||
return (
|
||||
<div className="row">
|
||||
<div className="col-auto" style={{ width: '60px' }}>
|
||||
<span className={`badge bg-${operationColorMapping[operation]}`}>{operation}</span>
|
||||
</div>
|
||||
|
||||
<div className="col">
|
||||
<span>{path}</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
return 'Select an operation';
|
||||
}
|
||||
};
|
||||
|
||||
computeOperationSelectionOptions = (operationOptions) => {
|
||||
let options = [];
|
||||
const paths = operationOptions?.paths;
|
||||
|
||||
if (paths) {
|
||||
for (const path of Object.keys(paths)) {
|
||||
for (const operation of Object.keys(paths[path])) {
|
||||
options.push({
|
||||
value: `${operation},${path}`,
|
||||
name: path,
|
||||
operation: operation,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return options;
|
||||
};
|
||||
|
||||
render() {
|
||||
const { options, specJson, loadingSpec } = this.state;
|
||||
const selectedOperation = options?.selectedOperation;
|
||||
|
||||
let pathParams = [];
|
||||
let queryParams = [];
|
||||
let requestBody = [];
|
||||
|
||||
if (selectedOperation) {
|
||||
if (selectedOperation.parameters) {
|
||||
pathParams = selectedOperation.parameters.filter((param) => param.in === 'path');
|
||||
queryParams = selectedOperation.parameters.filter((param) => param.in === 'query');
|
||||
}
|
||||
|
||||
if (selectedOperation.requestBody) {
|
||||
const requestType = Object.keys(selectedOperation.requestBody.content)[0];
|
||||
requestBody = selectedOperation.requestBody.content[requestType];
|
||||
}
|
||||
}
|
||||
|
||||
const currentValue = this.state.options?.operation + ',' + this.props.options?.path ?? null;
|
||||
|
||||
return (
|
||||
<div>
|
||||
{loadingSpec && (
|
||||
<div className="p-3">
|
||||
<div className="spinner-border spinner-border-sm text-azure mx-2" role="status"></div>
|
||||
{this.props.t('stripe', 'Please wait while we load the OpenAPI specification for Stripe.')}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{options && !loadingSpec && (
|
||||
<div>
|
||||
<div className="d-flex g-2">
|
||||
<div className="col-12 form-label">
|
||||
<label className="form-label">{this.props.t('globals.operation', 'Operation')}</label>
|
||||
</div>
|
||||
<div className="col stripe-operation-options flex-grow-1" style={{ width: '90px', marginTop: 0 }}>
|
||||
<Select
|
||||
options={this.computeOperationSelectionOptions(specJson)}
|
||||
value={currentValue}
|
||||
onChange={(value) => this.changeOperation(value)}
|
||||
width={'100%'}
|
||||
useMenuPortal={true}
|
||||
customOption={this.renderOperationOption}
|
||||
styles={queryManagerSelectComponentStyle(this.props.darkMode, '100%')}
|
||||
useCustomStyles={true}
|
||||
/>
|
||||
|
||||
{selectedOperation && (
|
||||
<small
|
||||
style={{ margintTop: '10px' }}
|
||||
className="my-2"
|
||||
dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(selectedOperation.description) }}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{selectedOperation && (
|
||||
<div className={`row stripe-fields-row ${this.props.darkMode && 'theme-dark'}`}>
|
||||
{pathParams.length > 0 && (
|
||||
<div className={`path-fields ${Object.keys(requestBody.schema.properties).length === 0 && 'd-none'}`}>
|
||||
<h5 className="text-heading">{this.props.t('globals.path', 'PATH')}</h5>
|
||||
<div className="input-group-parent-container">
|
||||
{pathParams.map((param) => (
|
||||
<div className="input-group-wrapper" key={param.name}>
|
||||
<div className="input-group">
|
||||
<div className="col-auto field field-width-179">
|
||||
<input
|
||||
type="text"
|
||||
value={param.name}
|
||||
className="form-control border-0"
|
||||
placeholder="key"
|
||||
/>
|
||||
</div>
|
||||
<div className="col field overflow-hidden">
|
||||
<CodeHinter
|
||||
type="basic"
|
||||
initialValue={this.state.options.params.path[param.name]}
|
||||
placeholder={'Value'}
|
||||
onChange={(value) => this.changeParam('path', param.name, value)}
|
||||
/>
|
||||
</div>
|
||||
<span
|
||||
className="col-auto field-width-28 d-flex"
|
||||
role="button"
|
||||
onClick={() => this.removeParam('path', param.name)}
|
||||
>
|
||||
<svg
|
||||
width="100%"
|
||||
height="100%"
|
||||
viewBox="0 0 12 13"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M5.99931 6.97508L11.0242 12.0014L12 11.027L6.9737 6.00069L12 0.975767L11.0256 0L5.99931 5.0263L0.974388 0L0 0.975767L5.02492 6.00069L0 11.0256L0.974388 12.0014L5.99931 6.97508Z"
|
||||
fill="#11181C"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{queryParams.length > 0 && (
|
||||
<div
|
||||
className={`query-fields ${Object.keys(requestBody.schema.properties).length === 0 && 'd-none'}`}
|
||||
>
|
||||
<h5 className="text-heading">{this.props.t('globals.query'.toUpperCase(), 'QUERY')}</h5>
|
||||
<div className="input-group-parent-container">
|
||||
{queryParams.map((param) => (
|
||||
<div className="input-group-wrapper" key={param.name}>
|
||||
<div className="input-group">
|
||||
<div className="col-auto field field-width-179">
|
||||
<input
|
||||
type="text"
|
||||
value={param.name}
|
||||
className="form-control"
|
||||
placeholder="key"
|
||||
disabled
|
||||
/>
|
||||
</div>
|
||||
<div className="col field overflow-hidden">
|
||||
<CodeHinter
|
||||
type="basic"
|
||||
initialValue={this.state.options.params?.query[param.name] ?? ''}
|
||||
placeholder={'Value'}
|
||||
onChange={(value) => this.changeParam('query', param.name, value)}
|
||||
/>
|
||||
</div>
|
||||
<span
|
||||
className="col-auto field-width-28 d-flex"
|
||||
role="button"
|
||||
onClick={() => this.removeParam('query', param.name)}
|
||||
>
|
||||
<svg
|
||||
width="100%"
|
||||
height="100%"
|
||||
viewBox="0 0 12 13"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M5.99931 6.97508L11.0242 12.0014L12 11.027L6.9737 6.00069L12 0.975767L11.0256 0L5.99931 5.0263L0.974388 0L0 0.975767L5.02492 6.00069L0 11.0256L0.974388 12.0014L5.99931 6.97508Z"
|
||||
fill="#11181C"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{requestBody.schema.properties && (
|
||||
<div
|
||||
className={`request-body-fields d-flex ${
|
||||
Object.keys(requestBody.schema.properties).length === 0 && 'd-none'
|
||||
} `}
|
||||
>
|
||||
<h5 className="text-heading form-label">{this.props.t('globals.requestBody', 'REQUEST BODY')}</h5>
|
||||
<div
|
||||
className={`flex-grow-1 ${
|
||||
Object.keys(requestBody.schema.properties).length >= 1 && 'input-group-parent-container'
|
||||
}`}
|
||||
>
|
||||
{Object.keys(requestBody.schema.properties).map((param) => (
|
||||
<div className="input-group-wrapper" key={param.name}>
|
||||
<div className="input-group">
|
||||
<div className="col-auto field field-width-179">
|
||||
<input type="text" value={param} className="form-control" placeholder="key" disabled />
|
||||
</div>
|
||||
<div className="col field overflow-hidden">
|
||||
<CodeHinter
|
||||
type="basic"
|
||||
initialValue={this.state.options.params?.request[param] ?? ''}
|
||||
placeholder={'Value'}
|
||||
onChange={(value) => this.changeParam('request', param, value)}
|
||||
/>
|
||||
</div>
|
||||
<span
|
||||
className="col-auto field-width-28 d-flex"
|
||||
role="button"
|
||||
onClick={() => this.removeParam('request', param)}
|
||||
>
|
||||
<svg
|
||||
width="100%"
|
||||
height="100%"
|
||||
viewBox="0 0 12 13"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M5.99931 6.97508L11.0242 12.0014L12 11.027L6.9737 6.00069L12 0.975767L11.0256 0L5.99931 5.0263L0.974388 0L0 0.975767L5.02492 6.00069L0 11.0256L0.974388 12.0014L5.99931 6.97508Z"
|
||||
fill="#11181C"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export const Stripe = withTranslation()(StripeComponent);
|
||||
|
|
@ -6,7 +6,6 @@ import { Restapi } from './Restapi';
|
|||
// eslint-disable-next-line import/no-unresolved
|
||||
import { Runjs } from './Runjs';
|
||||
import { Runpy } from './Runpy';
|
||||
import { Stripe } from './Stripe';
|
||||
import { Openapi } from './Openapi';
|
||||
import Grpc from './GRPC';
|
||||
import tooljetDbOperations from './TooljetDatabase/operations.json';
|
||||
|
|
@ -36,7 +35,6 @@ export const allSources = {
|
|||
Restapi,
|
||||
Runjs,
|
||||
Runpy,
|
||||
Stripe,
|
||||
Openapi,
|
||||
Grpc,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -289,6 +289,7 @@ export const tableConfig = {
|
|||
onCellValueChanged: { displayName: 'Cell value changed' },
|
||||
onFilterChanged: { displayName: 'Filter changed' },
|
||||
onNewRowsAdded: { displayName: 'Add new rows' },
|
||||
onTableDataDownload: { displayName: 'Download data' },
|
||||
},
|
||||
styles: {
|
||||
textColor: {
|
||||
|
|
|
|||
|
|
@ -13,19 +13,21 @@ import {
|
|||
CloudStorageSources,
|
||||
CommonlyUsedDataSources,
|
||||
} from '@/Editor/DataSourceManager/SourceComponents';
|
||||
import { pluginsService, globalDatasourceService, authenticationService } from '@/_services';
|
||||
import { pluginsService, globalDatasourceService, authenticationService, marketplaceService } from '@/_services';
|
||||
import { Card } from '@/_ui/Card';
|
||||
import { SegregatedList } from '../SegregatedList';
|
||||
import { SearchBox } from '@/_components';
|
||||
import { ButtonSolid } from '@/_ui/AppButton/AppButton';
|
||||
import SolidIcon from '@/_ui/Icon/SolidIcons';
|
||||
import { BreadCrumbContext } from '@/App';
|
||||
import { canDeleteDataSource } from '@/_helpers';
|
||||
import { fetchAndSetWindowTitle, pageTitles } from '@white-label/whiteLabelling';
|
||||
import HeaderSkeleton from '../../_ui/FolderSkeleton/HeaderSkeleton';
|
||||
import Skeleton from 'react-loading-skeleton';
|
||||
export const GlobalDataSourcesPage = ({ darkMode = false, updateSelectedDatasource }) => {
|
||||
const containerRef = useRef(null);
|
||||
const [plugins, setPlugins] = useState([]);
|
||||
const [marketplacePlugins, setMarketplacePlugins] = useState([]);
|
||||
const [filteredDataSources, setFilteredDataSources] = useState([]);
|
||||
const [queryString, setQueryString] = useState('');
|
||||
const [addingDataSource, setAddingDataSource] = useState(false);
|
||||
|
|
@ -54,7 +56,10 @@ export const GlobalDataSourcesPage = ({ darkMode = false, updateSelectedDatasour
|
|||
setCurrentEnvironment,
|
||||
activeDatasourceList,
|
||||
setActiveDatasourceList,
|
||||
canCreateDataSource,
|
||||
canUpdateDataSource,
|
||||
isLoading,
|
||||
environmentLoading,
|
||||
} = useContext(GlobalDataSourcesContext);
|
||||
|
||||
const { updateSidebarNAV } = useContext(BreadCrumbContext);
|
||||
|
|
@ -66,6 +71,13 @@ export const GlobalDataSourcesPage = ({ darkMode = false, updateSelectedDatasour
|
|||
.catch((error) => {
|
||||
toast.error(error?.message || 'Failed to fetch plugins');
|
||||
});
|
||||
|
||||
marketplaceService
|
||||
.findAll()
|
||||
.then(({ data = [] }) => setMarketplacePlugins([...data]))
|
||||
.catch((error) => {
|
||||
toast.error(error?.message || 'Failed to fetch plugins');
|
||||
});
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
|
|
@ -320,23 +332,38 @@ export const GlobalDataSourcesPage = ({ darkMode = false, updateSelectedDatasour
|
|||
};
|
||||
});
|
||||
|
||||
const pluginsWithTags = marketplacePlugins.reduce((acc, plugin) => {
|
||||
const isInDatasources = datasources.some((datasource) => {
|
||||
return datasource.kind === plugin.id || datasource.pluginId === plugin.id || datasource.plugin_id === plugin.id;
|
||||
});
|
||||
if (isInDatasources && plugin.tags) {
|
||||
acc[plugin.id] = plugin.tags;
|
||||
}
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="row row-deck mt-3">
|
||||
{datasources.map((item) => (
|
||||
<Card
|
||||
key={item.key}
|
||||
darkMode={darkMode}
|
||||
title={item.title}
|
||||
src={item?.src}
|
||||
usePluginIcon={isEmpty(item?.iconFile?.data)}
|
||||
height={'35px'}
|
||||
width={'35px'}
|
||||
actionButton={addDataSourceBtn(item)}
|
||||
className="datasource-card"
|
||||
titleClassName={'datasource-card-title'}
|
||||
/>
|
||||
))}
|
||||
{datasources.map((item) => {
|
||||
const tags =
|
||||
pluginsWithTags[item.kind] || pluginsWithTags[item.pluginId] || pluginsWithTags[item.plugin_id] || [];
|
||||
return (
|
||||
<Card
|
||||
key={item.key}
|
||||
darkMode={darkMode}
|
||||
title={item.title}
|
||||
src={item?.src}
|
||||
usePluginIcon={isEmpty(item?.iconFile?.data)}
|
||||
height={'35px'}
|
||||
width={'35px'}
|
||||
actionButton={addDataSourceBtn(item)}
|
||||
className="datasource-card"
|
||||
titleClassName={'datasource-card-title'}
|
||||
tags={tags}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
{type === 'Plugins' && (
|
||||
<div style={{ height: '122px', width: '164px' }} className={`col-md-2 mb-4 `}>
|
||||
<div
|
||||
|
|
@ -352,7 +379,7 @@ export const GlobalDataSourcesPage = ({ darkMode = false, updateSelectedDatasour
|
|||
data-cy={`data-source-add-plugin`}
|
||||
>
|
||||
<div className="card-body">
|
||||
<center style={{ paddingTop: '5px' }}>
|
||||
<center style={{ paddingTop: '5px', marginTop: '20px' }}>
|
||||
<SolidIcon
|
||||
name="plus"
|
||||
fill={'var(--icon-default)'}
|
||||
|
|
@ -418,6 +445,15 @@ export const GlobalDataSourcesPage = ({ darkMode = false, updateSelectedDatasour
|
|||
return dataSourceList;
|
||||
};
|
||||
|
||||
const selectedPlugin = marketplacePlugins.find(
|
||||
(plugin) =>
|
||||
plugin.id === selectedDataSource?.kind ||
|
||||
plugin.id === selectedDataSource?.pluginId ||
|
||||
plugin.id === selectedDataSource?.plugin_id
|
||||
);
|
||||
|
||||
const tags = selectedPlugin?.tags || [];
|
||||
|
||||
return (
|
||||
<div className="row gx-0">
|
||||
<Sidebar renderSidebarList={renderSidebarList} updateSelectedDatasource={updateSelectedDatasource} />
|
||||
|
|
@ -438,6 +474,9 @@ export const GlobalDataSourcesPage = ({ darkMode = false, updateSelectedDatasour
|
|||
container={selectedDataSource ? containerRef?.current : null}
|
||||
isEditing={isEditing}
|
||||
updateSelectedDatasource={updateSelectedDatasource}
|
||||
showSaveBtn={canCreateDataSource() || canUpdateDataSource(selectedDataSource?.id) || canDeleteDataSource()}
|
||||
environmentLoading={environmentLoading}
|
||||
tags={tags}
|
||||
/>
|
||||
)}
|
||||
{isLoading && loadingState()}
|
||||
|
|
|
|||
|
|
@ -193,17 +193,19 @@ const ConstantForm = ({
|
|||
{error['name']}
|
||||
</span>
|
||||
{!error['name'] && (
|
||||
<small style={{ color: 'var(--text-placeholder)' }}>Name must be unique and max 50 characters</small>
|
||||
<small style={{ color: 'var(--text-placeholder)' }} data-cy="name-info">
|
||||
Name must be unique and max 50 characters
|
||||
</small>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label className="form-label" data-cy="name-label">
|
||||
<label className="form-label" data-cy="type-label">
|
||||
Type
|
||||
</label>
|
||||
<div className="radio-group" data-tooltip-id="type-tooltip">
|
||||
<div className="radio-item">
|
||||
<label style={{ color: mode === 'edit' ? '#adb5bd' : 'inherit' }}>
|
||||
<label style={{ color: mode === 'edit' ? '#adb5bd' : 'inherit' }} data-cy="global-constants-label">
|
||||
<input
|
||||
type="radio"
|
||||
name="type"
|
||||
|
|
@ -211,15 +213,16 @@ const ConstantForm = ({
|
|||
checked={fields['type'] === Constants.Global}
|
||||
onChange={handleFieldChange}
|
||||
disabled={mode === 'edit'}
|
||||
data-cy="global-constants-input"
|
||||
/>
|
||||
Global constants
|
||||
</label>
|
||||
<small style={{ color: mode === 'edit' ? '#adb5bd' : 'inherit' }}>
|
||||
<small style={{ color: mode === 'edit' ? '#adb5bd' : 'inherit' }} data-cy="global-constants-info">
|
||||
The values can be used anywhere in the product
|
||||
</small>
|
||||
</div>
|
||||
<div className="radio-item">
|
||||
<label style={{ color: mode === 'edit' ? '#adb5bd' : 'inherit' }}>
|
||||
<label style={{ color: mode === 'edit' ? '#adb5bd' : 'inherit' }} data-cy="secrets-constants-label">
|
||||
<input
|
||||
type="radio"
|
||||
name="type"
|
||||
|
|
@ -227,10 +230,11 @@ const ConstantForm = ({
|
|||
checked={fields['type'] === Constants.Secret}
|
||||
onChange={handleFieldChange}
|
||||
disabled={mode === 'edit'}
|
||||
data-cy="secrets-constants-input"
|
||||
/>
|
||||
Secrets
|
||||
</label>
|
||||
<small style={{ color: mode === 'edit' ? '#adb5bd' : 'inherit' }}>
|
||||
<small style={{ color: mode === 'edit' ? '#adb5bd' : 'inherit' }} data-cy="secrets-constants-info">
|
||||
The values are hidden and can only be used in data sources and queries
|
||||
</small>
|
||||
</div>
|
||||
|
|
@ -246,7 +250,7 @@ const ConstantForm = ({
|
|||
<label className="form-label" data-cy="value-label">
|
||||
Value
|
||||
</label>
|
||||
<small className="text-green d-flex align-items-center" data-cy="encrypted-label">
|
||||
<small className="text-green d-flex align-items-center" data-cy="form-encrypted-label">
|
||||
<img
|
||||
className="encrypted-icon me-1"
|
||||
src="assets/images/icons/padlock.svg"
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ const ConstantTable = ({
|
|||
{' '}
|
||||
<small
|
||||
className="text-green d-flex align-items-center justify-content-end"
|
||||
data-cy="encrypted-label"
|
||||
data-cy="table-encrypted-label"
|
||||
>
|
||||
<img
|
||||
className="encrypted-icon me-1"
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ const EmptyState = ({ canCreateVariable, setIsManageVarDrawerOpen, isLoading, se
|
|||
</p>
|
||||
{canCreateVariable && searchTerm === '' && (
|
||||
<ButtonSolid
|
||||
data-cy="add-new-constant-button"
|
||||
data-cy="table-add-new-constant-button"
|
||||
vaiant="primary"
|
||||
onClick={() => setIsManageVarDrawerOpen(true)}
|
||||
className="add-new-constant-button"
|
||||
|
|
|
|||
|
|
@ -454,7 +454,7 @@ const ManageOrgConstantsComponent = ({ darkMode }) => {
|
|||
<div className="workspace-setting-buttons-wrap">
|
||||
{canCreateVariable() && (
|
||||
<ButtonSolid
|
||||
data-cy="add-new-constant-button"
|
||||
data-cy="form-add-new-constant-button"
|
||||
variant="primary"
|
||||
onClick={() => {
|
||||
setMode(() => MODES.CREATE);
|
||||
|
|
|
|||
|
|
@ -237,7 +237,7 @@ function InviteUsersForm({
|
|||
className="invite-email-body"
|
||||
id="inviteByEmail"
|
||||
>
|
||||
<label className="form-label" data-cy="label-full-name-input-field">
|
||||
<label className="form-label" data-cy="name-label">
|
||||
Name
|
||||
</label>
|
||||
<div className="form-group mb-3 ">
|
||||
|
|
@ -255,7 +255,7 @@ function InviteUsersForm({
|
|||
name="fullName"
|
||||
onChange={changeNewUserOption.bind(this, 'fullName')}
|
||||
value={fields['fullName']}
|
||||
data-cy="input-field-full-name"
|
||||
data-cy="name-input"
|
||||
disabled={isEditing}
|
||||
/>
|
||||
<span className="text-danger" data-cy="error-message-fullname">
|
||||
|
|
@ -265,7 +265,7 @@ function InviteUsersForm({
|
|||
</ToolTip>
|
||||
</div>
|
||||
<div className="form-group mb-3 ">
|
||||
<label className="form-label" data-cy="label-email-input-field">
|
||||
<label className="form-label" data-cy="email-label">
|
||||
{t('header.organization.menus.manageUsers.emailAddress', 'Email Address')}
|
||||
</label>
|
||||
<ToolTip
|
||||
|
|
@ -283,7 +283,7 @@ function InviteUsersForm({
|
|||
name="email"
|
||||
onChange={changeNewUserOption.bind(this, 'email')}
|
||||
value={fields['email']}
|
||||
data-cy="input-field-email"
|
||||
data-cy="email-input"
|
||||
disabled={isEditing}
|
||||
/>
|
||||
<span className="text-danger" data-cy="error-message-email">
|
||||
|
|
@ -293,7 +293,7 @@ function InviteUsersForm({
|
|||
</ToolTip>
|
||||
</div>
|
||||
<div className="form-group mb-3 manage-groups-invite-form" data-cy="user-group-select">
|
||||
<label className="form-label" data-cy="label-group-input-field">
|
||||
<label className="form-label" data-cy="user-group-label">
|
||||
{isEditing
|
||||
? 'User groups'
|
||||
: t('header.organization.menus.manageUsers.selectGroup', 'Select Group')}
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@ import cx from 'classnames';
|
|||
import { pluginsService } from '@/_services';
|
||||
import { toast } from 'react-hot-toast';
|
||||
import Spinner from '@/_ui/Spinner';
|
||||
import { capitalizeFirstLetter } from './utils';
|
||||
import { capitalizeFirstLetter, useTagsByPluginId } from './utils';
|
||||
import { ConfirmDialog } from '@/_components';
|
||||
import Icon from '@/_ui/Icon/SolidIcons';
|
||||
|
||||
export const InstalledPlugins = ({
|
||||
allPlugins = [],
|
||||
|
|
@ -14,7 +15,7 @@ export const InstalledPlugins = ({
|
|||
ENABLE_MARKETPLACE_DEV_MODE,
|
||||
}) => {
|
||||
return (
|
||||
<div className="col-9 pb-3">
|
||||
<div className="col-9 pb-3" style={{ marginLeft: 'auto' }}>
|
||||
{fetching && (
|
||||
<div className="m-auto text-center">
|
||||
<Spinner />
|
||||
|
|
@ -53,7 +54,8 @@ const InstalledPluginCard = ({ plugin, marketplacePlugin, fetchPlugins, isDevMod
|
|||
const [isDeletingPlugin, setDeletingPlugin] = React.useState(false);
|
||||
|
||||
const darkMode = localStorage.getItem('darkMode') === 'true';
|
||||
const { id, name } = plugin;
|
||||
const { id, name, pluginId } = plugin;
|
||||
const { tags } = useTagsByPluginId(pluginId);
|
||||
|
||||
const executePluginDeletion = () => {
|
||||
setDeleteModalVisibility(true);
|
||||
|
|
@ -143,7 +145,19 @@ const InstalledPluginCard = ({ plugin, marketplacePlugin, fetchPlugins, isDevMod
|
|||
</span>
|
||||
</div>
|
||||
<div className="col">
|
||||
<div className="font-weight-medium text-capitalize">{plugin.name}</div>
|
||||
<div className="d-flex align-items-center tw-gap-[6px]">
|
||||
<div className="font-weight-medium text-capitalize">{plugin.name}</div>
|
||||
{tags.map((tag) => {
|
||||
if (tag === 'AI') {
|
||||
return (
|
||||
<div key={tag} className="tag-container">
|
||||
<Icon name="AI-tag" />
|
||||
<span>{tag}</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
})}
|
||||
</div>
|
||||
<div>{plugin.description}</div>
|
||||
</div>
|
||||
<div className="col-2">
|
||||
|
|
|
|||
|
|
@ -3,12 +3,15 @@ import config from 'config';
|
|||
import cx from 'classnames';
|
||||
import { toast } from 'react-hot-toast';
|
||||
import { pluginsService } from '@/_services';
|
||||
import { capitalizeFirstLetter } from './utils';
|
||||
import { capitalizeFirstLetter, useTagsByPluginId } from './utils';
|
||||
import Icon from '@/_ui/Icon/SolidIcons';
|
||||
|
||||
export const MarketplaceCard = ({ id, name, repo, description, version, isInstalled = false }) => {
|
||||
const [installed, setInstalled] = React.useState(isInstalled);
|
||||
const [installing, setInstalling] = React.useState(false);
|
||||
|
||||
const { tags } = useTagsByPluginId(id);
|
||||
|
||||
React.useEffect(() => {
|
||||
setInstalled(isInstalled);
|
||||
}, [isInstalled]);
|
||||
|
|
@ -53,7 +56,19 @@ export const MarketplaceCard = ({ id, name, repo, description, version, isInstal
|
|||
</span>
|
||||
</div>
|
||||
<div className="col">
|
||||
<div className="font-weight-medium text-capitalize">{name}</div>
|
||||
<div className="tw-flex tw-items-center tw-gap-[6px]">
|
||||
<div className="font-weight-medium text-capitalize">{name}</div>
|
||||
{tags.map((tag) => {
|
||||
if (tag === 'AI') {
|
||||
return (
|
||||
<div key={tag} className="tag-container">
|
||||
<Icon name="AI-tag" />
|
||||
<span>{tag}</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
})}
|
||||
</div>
|
||||
<div>{description}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ export const MarketplacePlugins = ({ allPlugins = [] }) => {
|
|||
}, []);
|
||||
|
||||
return (
|
||||
<div className="col-9 pb-3">
|
||||
<div className="col-9 pb-3" style={{ marginLeft: 'auto' }}>
|
||||
<div className="row row-cards">
|
||||
{allPlugins?.map(({ id, name, repo, version, description }) => {
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -1,3 +1,25 @@
|
|||
import { useEffect, useState } from 'react';
|
||||
import { marketplaceService } from '@/_services';
|
||||
import toast from 'react-hot-toast';
|
||||
|
||||
export function capitalizeFirstLetter(str) {
|
||||
return str.charAt(0).toUpperCase() + str.slice(1);
|
||||
}
|
||||
|
||||
export const useTagsByPluginId = (id) => {
|
||||
const [tags, setTags] = useState([]);
|
||||
|
||||
useEffect(() => {
|
||||
marketplaceService
|
||||
.findAll()
|
||||
.then(({ data = [] }) => {
|
||||
const plugin = data.find((plugin) => plugin.id === id);
|
||||
setTags(plugin?.tags || []);
|
||||
})
|
||||
.catch((error) => {
|
||||
toast.error(error?.message || 'Failed to fetch plugins');
|
||||
});
|
||||
}, [id]);
|
||||
|
||||
return { tags };
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,17 +1,36 @@
|
|||
import React, { useState, useContext } from 'react';
|
||||
import React, { useState } from 'react';
|
||||
import cx from 'classnames';
|
||||
import OverlayTrigger from 'react-bootstrap/OverlayTrigger';
|
||||
import Popover from 'react-bootstrap/Popover';
|
||||
import { FilterForm } from '../Forms/FilterForm';
|
||||
import { isEmpty } from 'lodash';
|
||||
// import { pluralize } from '@/_helpers/utils';
|
||||
import { pluralize } from '@/_helpers/utils';
|
||||
import { useMounted } from '@/_hooks/use-mount';
|
||||
import SolidIcon from '@/_ui/Icon/SolidIcons';
|
||||
import { ButtonSolid } from '@/_ui/AppButton/AppButton';
|
||||
import AddRectangle from '@/_ui/Icon/bulkIcons/AddRectangle';
|
||||
import ClearIndicator from '@/_ui/Icon/bulkIcons/ClearIndicator';
|
||||
import InfoIcon from '@assets/images/icons/info.svg';
|
||||
import { deepClone } from '@/_helpers/utilities/utils.helpers';
|
||||
import './styles.scss';
|
||||
import { toast } from 'react-hot-toast';
|
||||
|
||||
const Filter = ({ filters, setFilters, handleBuildFilterQuery, resetFilterQuery, setFilterEnable, filterEnable }) => {
|
||||
const Filter = ({
|
||||
filters,
|
||||
setFilters,
|
||||
handleBuildFilterQuery,
|
||||
resetFilterQuery,
|
||||
setFilterEnable,
|
||||
filterEnable,
|
||||
setActiveFilters,
|
||||
}) => {
|
||||
const [tempFilters, setTempFilters] = useState(deepClone(filters));
|
||||
const [show, setShow] = useState(false);
|
||||
const darkMode = localStorage.getItem('darkMode') === 'true';
|
||||
const filterKeys = Object.keys(filters);
|
||||
const filterKeys = Object.keys(tempFilters);
|
||||
const tempFilterCount = Object.keys(tempFilters).length;
|
||||
const filterCount = Object.keys(filters).length;
|
||||
const validFilterCountRef = React.useRef(0);
|
||||
const isMounted = useMounted();
|
||||
|
||||
const reset = () => {
|
||||
|
|
@ -19,39 +38,133 @@ const Filter = ({ filters, setFilters, handleBuildFilterQuery, resetFilterQuery,
|
|||
setShow(false);
|
||||
};
|
||||
|
||||
const generateMessage = (operator) => {
|
||||
const operatorMessage = {
|
||||
gte: 'Greater than or equal',
|
||||
lt: 'Less than',
|
||||
gt: 'Greater than',
|
||||
eq: 'Equals',
|
||||
lte: 'Less than or equal',
|
||||
neq: 'Not equal',
|
||||
};
|
||||
return operatorMessage[operator];
|
||||
};
|
||||
|
||||
React.useEffect(() => {
|
||||
setActiveFilters(filterCount);
|
||||
}, [filterCount, setActiveFilters]);
|
||||
|
||||
const allValidFilters = React.useMemo(() => {
|
||||
const filteredFilters = Object.values(tempFilters).filter(
|
||||
({ column, operator, value }) => column || operator || value
|
||||
);
|
||||
if (filteredFilters.length === 0 && filterCount === 0) {
|
||||
validFilterCountRef.current = 0;
|
||||
return false;
|
||||
}
|
||||
if (filteredFilters.length === 0 && filterCount !== 0 && tempFilterCount !== 0) {
|
||||
validFilterCountRef.current = 0;
|
||||
return false;
|
||||
}
|
||||
validFilterCountRef.current = filteredFilters.length;
|
||||
return filteredFilters.every(({ column, operator, value }) => column && operator && value);
|
||||
}, [tempFilters]);
|
||||
|
||||
const popover = (
|
||||
<Popover id="storage-filter-popover" className={cx({ 'dark-theme': darkMode })} data-cy="filter-section">
|
||||
<Popover.Body bsPrefix="storage-filter-popover">
|
||||
<div className="card-body" data-cy="filter-card-body">
|
||||
{Object.values(filters).map((filter, index) => {
|
||||
return (
|
||||
<div key={index}>
|
||||
<FilterForm {...filter} filters={filters} index={filterKeys[index]} setFilters={setFilters} />
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
<div
|
||||
className="card-footer cursor-pointer"
|
||||
data-cy="filter-card-footer"
|
||||
onClick={() =>
|
||||
setFilters((prevFilters) => ({ ...prevFilters, [+Object.keys(prevFilters).pop() + 1 || 0]: {} }))
|
||||
}
|
||||
>
|
||||
<svg
|
||||
width="11"
|
||||
height="11"
|
||||
viewBox="0 0 11 11"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
data-cy="add-condition-link"
|
||||
<Popover
|
||||
id="storage-filter-popover"
|
||||
className={cx('filter-popup', { 'dark-theme': darkMode })}
|
||||
data-cy="filter-section"
|
||||
>
|
||||
<Popover.Body bsPrefix="storage-filter-popover" style={{ height: '100%' }}>
|
||||
<div className="filter-header">
|
||||
<span className="filter-heading">Filters</span>
|
||||
<span
|
||||
className="cursor-pointer"
|
||||
onClick={() => {
|
||||
setShow(false);
|
||||
setTempFilters(deepClone(filters));
|
||||
}}
|
||||
>
|
||||
<path
|
||||
d="M5.34554 10.0207C5.15665 10.0207 4.99832 9.95678 4.87054 9.829C4.74276 9.70123 4.67887 9.54289 4.67887 9.354V5.854H1.17887C0.989985 5.854 0.831651 5.79011 0.703874 5.66234C0.576096 5.53456 0.512207 5.37623 0.512207 5.18734C0.512207 4.99845 0.576096 4.84012 0.703874 4.71234C0.831651 4.58456 0.989985 4.52067 1.17887 4.52067H4.67887V1.02067C4.67887 0.831782 4.74276 0.673448 4.87054 0.54567C4.99832 0.417893 5.15665 0.354004 5.34554 0.354004C5.53443 0.354004 5.69276 0.417893 5.82054 0.54567C5.94832 0.673448 6.01221 0.831782 6.01221 1.02067V4.52067H9.51221C9.7011 4.52067 9.85943 4.58456 9.98721 4.71234C10.115 4.84012 10.1789 4.99845 10.1789 5.18734C10.1789 5.37623 10.115 5.53456 9.98721 5.66234C9.85943 5.79011 9.7011 5.854 9.51221 5.854H6.01221V9.354C6.01221 9.54289 5.94832 9.70123 5.82054 9.829C5.69276 9.95678 5.53443 10.0207 5.34554 10.0207Z"
|
||||
fill="#466BF2"
|
||||
/>
|
||||
</svg>
|
||||
Add Condition
|
||||
<SolidIcon name="remove" fill={darkMode ? '#C1C8CD' : '#6A727C'} />
|
||||
</span>
|
||||
</div>
|
||||
<div className="card-body filter-body" data-cy="filter-card-body">
|
||||
{tempFilterCount === 0 && (
|
||||
<div className="empty-filters-value">
|
||||
<InfoIcon style={{ width: '16px', marginRight: '5px' }} />
|
||||
<span>There are no filters added</span>
|
||||
</div>
|
||||
)}
|
||||
{tempFilterCount > 0 && (
|
||||
<>
|
||||
<div className="filter-title">
|
||||
<span className="width-lg">Column</span>
|
||||
<span className="width-sm">Operation</span>
|
||||
<span className="width-lg">Value</span>
|
||||
</div>
|
||||
{Object.values(tempFilters).map((filter, index) => {
|
||||
return (
|
||||
<div key={index} className="tw-pb-1 filter-content">
|
||||
<FilterForm
|
||||
{...filter}
|
||||
filters={tempFilters}
|
||||
index={filterKeys[index]}
|
||||
setFilters={setTempFilters}
|
||||
generateMessage={generateMessage}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</>
|
||||
)}
|
||||
<div className="tw-mt-1 tw-pl-2">
|
||||
<ButtonSolid
|
||||
variant="ghostBlue"
|
||||
size="sm"
|
||||
onClick={() =>
|
||||
setTempFilters((prevFilters) => ({ ...prevFilters, [+Object.keys(prevFilters).pop() + 1 || 0]: {} }))
|
||||
}
|
||||
>
|
||||
<AddRectangle width="15" fill="#3E63DD" opacity="1" secondaryFill="#ffffff" />
|
||||
Add filter
|
||||
</ButtonSolid>
|
||||
</div>
|
||||
</div>
|
||||
<div className="card-footer filter-footer" data-cy="filter-card-footer">
|
||||
{filterCount > 0 && tempFilterCount > 0 && (
|
||||
<ButtonSolid
|
||||
variant="ghostBlue"
|
||||
size="sm"
|
||||
onClick={() => {
|
||||
setTempFilters({});
|
||||
}}
|
||||
>
|
||||
<ClearIndicator width="15" fill="#3E63DD" opacity="1" secondaryFill="#ffffff" />
|
||||
Clear all
|
||||
</ButtonSolid>
|
||||
)}
|
||||
<ButtonSolid
|
||||
variant="tertiary"
|
||||
size="sm"
|
||||
onClick={() => {
|
||||
setTempFilters(deepClone(filters));
|
||||
document.activeElement.blur();
|
||||
}}
|
||||
>
|
||||
Cancel
|
||||
</ButtonSolid>
|
||||
<ButtonSolid
|
||||
variant="primary"
|
||||
size="sm"
|
||||
onClick={() => {
|
||||
setFilters(tempFilters);
|
||||
setShow(false);
|
||||
}}
|
||||
disabled={!allValidFilters || (filterCount === 0 && tempFilterCount === 0)}
|
||||
>
|
||||
Apply
|
||||
</ButtonSolid>
|
||||
</div>
|
||||
</Popover.Body>
|
||||
</Popover>
|
||||
|
|
@ -69,14 +182,34 @@ const Filter = ({ filters, setFilters, handleBuildFilterQuery, resetFilterQuery,
|
|||
reset();
|
||||
resetFilterQuery();
|
||||
} else {
|
||||
let validFilters = { ...filters };
|
||||
let hasInvalidFilter = false;
|
||||
|
||||
Object.keys(filters).map((key) => {
|
||||
if (!isEmpty(filters[key])) {
|
||||
const { column, operator, value } = filters[key];
|
||||
if (!isEmpty(column) && !isEmpty(operator) && !isEmpty(value)) {
|
||||
handleBuildFilterQuery(filters);
|
||||
if (value.toLowerCase() === 'null' && operator !== 'is') {
|
||||
delete validFilters[key];
|
||||
hasInvalidFilter = true;
|
||||
toast.error(
|
||||
`Invalid filter operation: Cannot use '${generateMessage(
|
||||
operator
|
||||
)}' operator with a NULL value for column '${column}'.`,
|
||||
{ position: 'top-center' }
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (hasInvalidFilter) {
|
||||
setFilters(validFilters);
|
||||
}
|
||||
|
||||
if (Object.keys(validFilters).length > 0) {
|
||||
handleBuildFilterQuery(validFilters);
|
||||
}
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [JSON.stringify(filters)]);
|
||||
|
|
@ -88,25 +221,58 @@ const Filter = ({ filters, setFilters, handleBuildFilterQuery, resetFilterQuery,
|
|||
trigger="click"
|
||||
show={show}
|
||||
onToggle={(show) => {
|
||||
if (show && isEmpty(filters)) setFilters({ 0: {} });
|
||||
if (show && isEmpty(filters)) setTempFilters({ 0: {} });
|
||||
if (show && !isEmpty(filters)) setTempFilters(deepClone(filters));
|
||||
setShow(show);
|
||||
}}
|
||||
placement="bottom-start"
|
||||
overlay={popover}
|
||||
>
|
||||
<button
|
||||
data-cy="filter-button"
|
||||
className={cx('tj-db-filter-btn tj-text-xsm font-weight-500 ghost-black-operation', {
|
||||
'tj-db-filter-btn-applied': areFiltersApplied,
|
||||
'tj-db-filter-btn-active': show,
|
||||
})}
|
||||
>
|
||||
<SolidIcon name="filter" width="14" fill={areFiltersApplied ? '#46A758' : show ? '#3E63DD' : '#889096'} />
|
||||
Filter
|
||||
{/* {areFiltersApplied && (
|
||||
<span>ed by {pluralize(Object.values(filters).filter(checkIsFilterObjectEmpty).length, 'column')}</span>
|
||||
)} */}
|
||||
</button>
|
||||
<div className={cx('tw-flex', 'tw-relative')}>
|
||||
<button
|
||||
data-cy="filter-button"
|
||||
className={cx('tj-db-filter-btn tj-text-xsm font-weight-500 ghost-black-operation', {
|
||||
'tj-db-filter-btn-applied': areFiltersApplied,
|
||||
'tj-db-filter-btn-active-filter': show && filterCount > 0,
|
||||
'tj-db-filter-btn-active': show && filterCount === 0,
|
||||
})}
|
||||
>
|
||||
<SolidIcon
|
||||
name="filter"
|
||||
width="14px"
|
||||
fill={
|
||||
areFiltersApplied
|
||||
? '#3E63DD'
|
||||
: show && filterCount === 0
|
||||
? '#ACB2B9'
|
||||
: show && filterCount > 0
|
||||
? '#4368E3'
|
||||
: '#889096'
|
||||
}
|
||||
/>
|
||||
<div className="tw-flex items-center tw-ml-[3px]">
|
||||
{filterCount > 0 ? (
|
||||
<span>{pluralize(validFilterCountRef.current, 'filter')}</span>
|
||||
) : (
|
||||
<div> Filter</div>
|
||||
)}
|
||||
</div>
|
||||
{/* {areFiltersApplied && (
|
||||
<span>ed by {pluralize(Object.values(filters).filter(checkIsFilterObjectEmpty).length, 'column')}</span>
|
||||
)} */}
|
||||
</button>
|
||||
{filterCount > 0 && (
|
||||
<div
|
||||
className="tw-absolute tw-right-[-20px] tw-z-50 tw-w-7 tw-h-7 tw-flex tw-items-center tw-justify-center tw-p-[7px] cursor-pointer tj-db-filter-clear-icon"
|
||||
onClick={() => {
|
||||
setFilters({});
|
||||
setTempFilters({});
|
||||
}}
|
||||
>
|
||||
<SolidIcon name="remove" width="14px" fill="#3E63DD" />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</OverlayTrigger>
|
||||
</>
|
||||
);
|
||||
|
|
|
|||
72
frontend/src/TooljetDatabase/Filter/styles.scss
Normal file
72
frontend/src/TooljetDatabase/Filter/styles.scss
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
.filter-popup{
|
||||
max-width: 560px !important;
|
||||
min-height: 252px !important;
|
||||
max-height: 420px !important;
|
||||
border: 1px solid var(--border-weak) !important;
|
||||
border-radius: 8px !important;
|
||||
}
|
||||
|
||||
.filter-title{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-left: 8px;
|
||||
margin-bottom: 2px;
|
||||
|
||||
span{
|
||||
font-family: IBM Plex Sans;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
line-height: 18px;
|
||||
text-align: left;
|
||||
color: var(--text-default)
|
||||
}
|
||||
|
||||
.width-lg{
|
||||
width: 181.5px;
|
||||
}
|
||||
|
||||
.width-sm{
|
||||
width: 120px;
|
||||
}
|
||||
}
|
||||
|
||||
.filter-body{
|
||||
padding: 24px 16px;
|
||||
max-height: calc(420px - 56px - 64px);
|
||||
overflow-y: auto;
|
||||
scrollbar-gutter: stable;
|
||||
position: relative;
|
||||
|
||||
.empty-filters-value{
|
||||
border-radius: 6px;
|
||||
padding: 10px;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
height: 32px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 10px;
|
||||
color: #687076;
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
line-height: 20px;
|
||||
border: 1px dashed #E6E8EB;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar{
|
||||
display: none;
|
||||
}
|
||||
&:hover::-webkit-scrollbar{
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.filter-footer{
|
||||
height: 64px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
gap: 8px;
|
||||
border-top: 1px solid var(--border-weak) !important;
|
||||
}
|
||||
|
|
@ -1,11 +1,13 @@
|
|||
import './styles.scss';
|
||||
import React, { useContext, useEffect, useState } from 'react';
|
||||
import Select from '@/_ui/Select';
|
||||
import { TooljetDatabaseContext } from '../index';
|
||||
import { operators } from '../constants';
|
||||
import { debounce } from 'lodash';
|
||||
import { ToolTip } from '@/_components';
|
||||
import SolidIcon from '@/_ui/Icon/SolidIcons';
|
||||
|
||||
export const FilterForm = ({ filters, setFilters, index, column = '', operator = '', value = '' }) => {
|
||||
export const FilterForm = ({ filters, setFilters, index, column = '', operator = '', value = '', generateMessage }) => {
|
||||
const { columns, setPageCount } = useContext(TooljetDatabaseContext);
|
||||
|
||||
const [filterInputValue, setFilterInputValue] = useState(value);
|
||||
|
|
@ -24,6 +26,10 @@ export const FilterForm = ({ filters, setFilters, index, column = '', operator =
|
|||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [filterInputValue]);
|
||||
|
||||
useEffect(() => {
|
||||
setFilterInputValue(value);
|
||||
}, [value]);
|
||||
|
||||
const handleColumnChange = (value) => {
|
||||
const prevFilters = { ...filters };
|
||||
prevFilters[index].column = value;
|
||||
|
|
@ -45,37 +51,66 @@ export const FilterForm = ({ filters, setFilters, index, column = '', operator =
|
|||
setPageCount(1);
|
||||
};
|
||||
|
||||
const handleSelectOpen = () => {
|
||||
document.body.classList.add('react-select-open');
|
||||
const selectControl = document.querySelector('.select-operation-field .react-select__control');
|
||||
if (selectControl) {
|
||||
const rect = selectControl.getBoundingClientRect();
|
||||
document.documentElement.style.setProperty('--select-width', `${rect.width}px`);
|
||||
document.documentElement.style.setProperty('0', `${rect.left}px`);
|
||||
document.documentElement.style.setProperty('100%', `${rect.bottom + window.scrollY}px`);
|
||||
}
|
||||
};
|
||||
|
||||
const handleSelectClose = () => {
|
||||
document.body.classList.remove('react-select-open');
|
||||
};
|
||||
|
||||
const displayColumns = columns.map(({ accessor }) => ({ value: accessor, label: accessor }));
|
||||
|
||||
return (
|
||||
<div className="row g-2 align-items-center">
|
||||
<div className="row g-0 d-flex align-items-center justify-content-center tw-w-[525px]">
|
||||
<div className="col-11">
|
||||
<div className="row g-2 align-items-center py-3">
|
||||
<div className="col-4 select-column-field" data-cy="select-column-field">
|
||||
<div className="row g-0 align-items-center">
|
||||
<div className="col-4 select-column-field width-lg" data-cy="select-column-field">
|
||||
<Select
|
||||
useMenuPortal={false}
|
||||
placeholder="Select column"
|
||||
placeholder="Select.."
|
||||
value={column}
|
||||
options={displayColumns}
|
||||
onChange={handleColumnChange}
|
||||
width="100%"
|
||||
borderRadius="8px 0px 0px 8px"
|
||||
onMenuOpen={handleSelectOpen}
|
||||
onMenuClose={handleSelectClose}
|
||||
/>
|
||||
</div>
|
||||
<div className="col-4 select-operation-field" data-cy="select-operation-field">
|
||||
<Select
|
||||
placeholder="Select operation"
|
||||
useMenuPortal={false}
|
||||
value={operator}
|
||||
options={operators}
|
||||
onChange={handleOperatorChange}
|
||||
/>
|
||||
</div>
|
||||
<ToolTip
|
||||
message={generateMessage(operator)}
|
||||
trigger={['hover']}
|
||||
delay={{ show: '0', hide: '0' }}
|
||||
show={['gt', 'lte', 'gte'].includes(operator)}
|
||||
>
|
||||
<div className="col-4 select-operation-field width-sm" data-cy="select-operation-field">
|
||||
<Select
|
||||
placeholder="Select.."
|
||||
useMenuPortal={false}
|
||||
value={operator}
|
||||
options={operators}
|
||||
onChange={handleOperatorChange}
|
||||
width="100%"
|
||||
borderRadius="0px"
|
||||
onMenuOpen={handleSelectOpen}
|
||||
onMenuClose={handleSelectClose}
|
||||
/>
|
||||
</div>
|
||||
</ToolTip>
|
||||
<div className="col-4">
|
||||
<input
|
||||
value={filterInputValue}
|
||||
type="text"
|
||||
className="form-control css-zz6spl-container"
|
||||
className="form-control css-zz6spl-container input-element"
|
||||
data-cy="value-input-field"
|
||||
placeholder="Value"
|
||||
placeholder="Enter value"
|
||||
onChange={(event) => {
|
||||
setFilterInputValue(event.target.value);
|
||||
}}
|
||||
|
|
@ -83,7 +118,7 @@ export const FilterForm = ({ filters, setFilters, index, column = '', operator =
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-1 cursor-pointer" data-cy="delete-icon" onClick={handleDelete}>
|
||||
<div className="col-1 delete-icon-wrapper" data-cy="delete-icon" onClick={handleDelete}>
|
||||
<SolidIcon name="trash" fill="#E54D2E" width="14" />
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -776,4 +776,92 @@
|
|||
|
||||
.tooltip-inner {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.width-lg{
|
||||
width: 181.5px;
|
||||
}
|
||||
|
||||
.width-sm{
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
.input-element{
|
||||
width: 181.5px !important;
|
||||
background-color: transparent !important;
|
||||
color: var(--text-default) !important;
|
||||
border-radius: 0px;
|
||||
border: 1px solid var(--border-default) !important;
|
||||
}
|
||||
|
||||
.delete-icon-wrapper{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 32px;
|
||||
width: 32px;
|
||||
border: 1px solid var(--border-default);
|
||||
border-radius: 0px 8px 8px 0px;
|
||||
cursor: pointer;
|
||||
border-left: none;
|
||||
}
|
||||
|
||||
.select-operation-field{
|
||||
.react-select__control{
|
||||
.react-select__value-container{
|
||||
position: relative;
|
||||
.react-select__input-container{
|
||||
position: absolute;
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.select-operation-field,
|
||||
.select-column-field{
|
||||
position: static;
|
||||
.react-select__control {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
border-right: none !important;
|
||||
}
|
||||
.react-select__menu {
|
||||
position: fixed;
|
||||
z-index: 9999;
|
||||
left: var(--select-left);
|
||||
top: var(--select-top);
|
||||
}
|
||||
}
|
||||
|
||||
.select-column-field .react-select__menu {
|
||||
width: 181.5px;
|
||||
}
|
||||
|
||||
.select-operation-field .react-select__menu {
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
body.react-select-open .filter-body {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
body.react-select-open .select-operation-field {
|
||||
pointer-events: auto;
|
||||
}
|
||||
body.react-select-open .select-column-field {
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.select-operation-field,
|
||||
.select-column-field{
|
||||
.react-select__menu{
|
||||
.react-select__menu-list{
|
||||
overflow-y: hidden;
|
||||
|
||||
&:hover {
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -36,6 +36,7 @@ const Header = ({
|
|||
const darkMode = localStorage.getItem('darkMode') === 'true';
|
||||
const [isAddNewDataMenuOpen, setIsAddNewDataMenuOpen] = useState(false);
|
||||
const [bulkUploadFile, setBulkUploadFile] = useState(null);
|
||||
const [activeFilters, setActiveFilters] = useState(0);
|
||||
const [isBulkUploading, setIsBulkUploading] = useState(false);
|
||||
const [errors, setErrors] = useState({ client: [], server: [] });
|
||||
const [uploadResult, setUploadResult] = useState(null);
|
||||
|
|
@ -173,7 +174,7 @@ const Header = ({
|
|||
</ButtonSolid>
|
||||
</span>
|
||||
</AddNewDataPopOver>
|
||||
<div style={{ width: '70px' }}>
|
||||
<div style={{ width: '83px', marginRight: activeFilters > 0 ? '20px' : '0px' }}>
|
||||
<Filter
|
||||
filters={queryFilters}
|
||||
setFilters={setQueryFilters}
|
||||
|
|
@ -181,6 +182,7 @@ const Header = ({
|
|||
resetFilterQuery={resetFilterQuery}
|
||||
setFilterEnable={setFilterEnable}
|
||||
filterEnable={filterEnable}
|
||||
setActiveFilters={setActiveFilters}
|
||||
/>
|
||||
</div>
|
||||
<div style={{ width: '70px' }}>
|
||||
|
|
|
|||
361
frontend/src/_components/ApiEndpointInput.jsx
Normal file
361
frontend/src/_components/ApiEndpointInput.jsx
Normal file
|
|
@ -0,0 +1,361 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import { openapiService } from '@/_services';
|
||||
import Select from '@/_ui/Select';
|
||||
import { queryManagerSelectComponentStyle } from '@/_ui/Select/styles';
|
||||
import DOMPurify from 'dompurify';
|
||||
import { ToolTip } from '@/_components';
|
||||
import CodeHinter from '@/AppBuilder/CodeEditor';
|
||||
import { withTranslation } from 'react-i18next';
|
||||
import { isEmpty } from 'lodash';
|
||||
import PropTypes from 'prop-types';
|
||||
import SolidIcons from '@/_ui/Icon/SolidIcons';
|
||||
|
||||
const operationColorMapping = {
|
||||
get: 'azure',
|
||||
post: 'green',
|
||||
delete: 'red',
|
||||
put: 'yellow',
|
||||
};
|
||||
|
||||
const ApiEndpointInput = (props) => {
|
||||
const [loadingSpec, setLoadingSpec] = useState(true);
|
||||
const [options, setOptions] = useState(props.options);
|
||||
const [specJson, setSpecJson] = useState(null);
|
||||
|
||||
const fetchOpenApiSpec = () => {
|
||||
setLoadingSpec(true);
|
||||
openapiService
|
||||
.fetchSpecFromUrl(props.specUrl)
|
||||
.then((response) => response.text())
|
||||
.then((text) => {
|
||||
const data = JSON.parse(text);
|
||||
setSpecJson(data);
|
||||
setLoadingSpec(false);
|
||||
});
|
||||
};
|
||||
|
||||
const changeOperation = (value) => {
|
||||
const operation = value.split('/', 2)[0];
|
||||
const path = value.substring(value.indexOf('/'));
|
||||
const newOptions = { ...options, path, operation, selectedOperation: specJson.paths[path][operation] };
|
||||
setOptions(newOptions);
|
||||
props.optionsChanged(newOptions);
|
||||
};
|
||||
|
||||
const changeParam = (paramType, paramName, value) => {
|
||||
if (value === '') {
|
||||
removeParam(paramType, paramName);
|
||||
} else {
|
||||
const newOptions = {
|
||||
...options,
|
||||
params: {
|
||||
...options.params,
|
||||
[paramType]: {
|
||||
...options.params[paramType],
|
||||
[paramName]: value,
|
||||
},
|
||||
},
|
||||
};
|
||||
setOptions(newOptions);
|
||||
props.optionsChanged(newOptions);
|
||||
}
|
||||
};
|
||||
|
||||
const removeParam = (paramType, paramName) => {
|
||||
const newOptions = JSON.parse(JSON.stringify(options));
|
||||
delete newOptions['params'][paramType][paramName];
|
||||
setOptions(newOptions);
|
||||
props.optionsChanged(newOptions);
|
||||
};
|
||||
|
||||
const renderOperationOption = (data) => {
|
||||
const path = data.value.substring(data.value.indexOf('/'));
|
||||
const operation = data.operation;
|
||||
if (path && operation) {
|
||||
return (
|
||||
<div className="row">
|
||||
<div className="col-auto" style={{ width: '60px' }}>
|
||||
<span className={`badge bg-${operationColorMapping[operation]}`}>{operation}</span>
|
||||
</div>
|
||||
<div className="col">
|
||||
<span>{path}</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
return 'Select an operation';
|
||||
}
|
||||
};
|
||||
|
||||
const categorizeOperations = (operation, path, acc, category) => {
|
||||
const option = {
|
||||
value: `${operation}${path}`,
|
||||
label: `${path}`,
|
||||
name: path,
|
||||
operation: operation,
|
||||
};
|
||||
const existingCategory = acc.find((obj) => obj.label === category);
|
||||
if (existingCategory) {
|
||||
existingCategory.options.push(option);
|
||||
} else {
|
||||
acc.push({
|
||||
label: category,
|
||||
options: [option],
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const computeOperationSelectionOptions = () => {
|
||||
const paths = specJson?.paths;
|
||||
if (isEmpty(paths)) return [];
|
||||
|
||||
const pathGroups = Object.keys(paths).reduce((acc, path) => {
|
||||
const operations = Object.keys(paths[path]);
|
||||
const category = path.split('/')[2];
|
||||
operations.forEach((operation) => categorizeOperations(operation, path, acc, category));
|
||||
return acc;
|
||||
}, []);
|
||||
|
||||
return pathGroups;
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const queryParams = {
|
||||
path: props.options?.params?.path ?? {},
|
||||
query: props.options?.params?.query ?? {},
|
||||
request: props.options?.params?.request ?? {},
|
||||
};
|
||||
setLoadingSpec(true);
|
||||
setOptions({ ...props.options, params: queryParams });
|
||||
fetchOpenApiSpec();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div>
|
||||
{loadingSpec && (
|
||||
<div className="p-3">
|
||||
<div className="spinner-border spinner-border-sm text-azure mx-2" role="status"></div>
|
||||
{props.t('stripe', 'Please wait while we load the OpenAPI specification.')}
|
||||
</div>
|
||||
)}
|
||||
{options && !loadingSpec && (
|
||||
<div>
|
||||
<div className="d-flex g-2">
|
||||
<div className="col-12 form-label">
|
||||
<label className="form-label">{props.t('globals.operation', 'Operation')}</label>
|
||||
</div>
|
||||
<div className="col stripe-operation-options flex-grow-1" style={{ width: '90px', marginTop: 0 }}>
|
||||
<Select
|
||||
options={computeOperationSelectionOptions()}
|
||||
value={{
|
||||
operation: options?.operation,
|
||||
value: `${options?.operation}${options?.path}`,
|
||||
}}
|
||||
onChange={(value) => changeOperation(value)}
|
||||
width={'100%'}
|
||||
useMenuPortal={true}
|
||||
customOption={renderOperationOption}
|
||||
styles={queryManagerSelectComponentStyle(props.darkMode, '100%')}
|
||||
useCustomStyles={true}
|
||||
/>
|
||||
{options?.selectedOperation && (
|
||||
<small
|
||||
style={{ margintTop: '10px' }}
|
||||
className="my-2"
|
||||
dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(options?.selectedOperation?.description) }}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
{options?.selectedOperation && (
|
||||
<div className={`row stripe-fields-row ${props.darkMode && 'theme-dark'}`}>
|
||||
<RenderParameterFields
|
||||
parameters={options?.selectedOperation?.parameters}
|
||||
type="path"
|
||||
label={props.t('globals.path', 'PATH')}
|
||||
options={options}
|
||||
changeParam={changeParam}
|
||||
removeParam={removeParam}
|
||||
darkMode={props.darkMode}
|
||||
/>
|
||||
<RenderParameterFields
|
||||
parameters={options?.selectedOperation?.parameters}
|
||||
type="query"
|
||||
label={props.t('globals.query'.toUpperCase(), 'Query')}
|
||||
options={options}
|
||||
changeParam={changeParam}
|
||||
removeParam={removeParam}
|
||||
darkMode={props.darkMode}
|
||||
/>
|
||||
<RenderParameterFields
|
||||
parameters={
|
||||
options?.selectedOperation?.requestBody?.content[
|
||||
Object.keys(options?.selectedOperation?.requestBody?.content)[0]
|
||||
]?.schema?.properties ?? {}
|
||||
}
|
||||
type="request"
|
||||
label={props.t('globals.requestBody', 'REQUEST BODY')}
|
||||
options={options}
|
||||
changeParam={changeParam}
|
||||
removeParam={removeParam}
|
||||
darkMode={props.darkMode}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default withTranslation()(ApiEndpointInput);
|
||||
|
||||
ApiEndpointInput.propTypes = {
|
||||
options: PropTypes.object,
|
||||
specUrl: PropTypes.string,
|
||||
optionsChanged: PropTypes.func,
|
||||
darkMode: PropTypes.bool,
|
||||
t: PropTypes.func,
|
||||
};
|
||||
|
||||
const RenderParameterFields = ({ parameters, type, label, options, changeParam, removeParam, darkMode }) => {
|
||||
let filteredParams;
|
||||
if (type === 'request') {
|
||||
filteredParams = Object.keys(parameters);
|
||||
} else {
|
||||
filteredParams = parameters?.filter((param) => param.in === type);
|
||||
}
|
||||
|
||||
const paramLabelWithDescription = (param) => {
|
||||
return (
|
||||
<ToolTip message={type === 'request' ? DOMPurify.sanitize(parameters[param].description) : param.description}>
|
||||
<div className="cursor-help">
|
||||
<input
|
||||
type="text"
|
||||
value={type === 'request' ? param : param.name}
|
||||
className="form-control form-control-underline"
|
||||
placeholder="key"
|
||||
disabled
|
||||
/>
|
||||
</div>
|
||||
</ToolTip>
|
||||
);
|
||||
};
|
||||
|
||||
const paramLabelWithoutDescription = (param) => {
|
||||
return (
|
||||
<input
|
||||
type="text"
|
||||
value={type === 'request' ? param : param.name}
|
||||
className="form-control"
|
||||
placeholder="key"
|
||||
disabled
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const paramType = (param) => {
|
||||
return (
|
||||
<div className="p-2 text-muted">
|
||||
{type === 'query' &&
|
||||
param?.schema?.anyOf &&
|
||||
param?.schema?.anyOf.map((type, i) =>
|
||||
i < param.schema?.anyOf.length - 1
|
||||
? type.type.substring(0, 3).toUpperCase() + '|'
|
||||
: type.type.substring(0, 3).toUpperCase()
|
||||
)}
|
||||
{(type === 'path' || (type === 'query' && !param?.schema?.anyOf)) &&
|
||||
param?.schema?.type?.substring(0, 3).toUpperCase()}
|
||||
{type === 'request' && parameters[param].type?.substring(0, 3).toUpperCase()}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const paramDetails = (param) => {
|
||||
return (
|
||||
<div className="col-auto d-flex field field-width-179 align-items-center">
|
||||
{(type === 'request' && parameters[param].description) || param?.description
|
||||
? paramLabelWithDescription(param)
|
||||
: paramLabelWithoutDescription(param)}
|
||||
{param.required && <span className="text-danger fw-bold">*</span>}
|
||||
{paramType(param)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const inputField = (param) => {
|
||||
return (
|
||||
<CodeHinter
|
||||
initialValue={(type === 'request' ? options?.params[type][param] : options?.params[type][param.name]) ?? ''}
|
||||
mode="text"
|
||||
placeholder={'Value'}
|
||||
theme={darkMode ? 'monokai' : 'duotone-light'}
|
||||
lineNumbers={false}
|
||||
onChange={(value) => {
|
||||
if (type === 'request') {
|
||||
changeParam(type, param, value);
|
||||
} else {
|
||||
changeParam(type, param.name, value);
|
||||
}
|
||||
}}
|
||||
height={'32px'}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const clearButton = (param) => {
|
||||
const handleClear = () => {
|
||||
if (type === 'request') {
|
||||
removeParam(type, param);
|
||||
} else {
|
||||
removeParam(type, param.name);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<span
|
||||
className="code-hinter-clear-btn"
|
||||
role="button"
|
||||
onClick={handleClear}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === 'Enter') {
|
||||
handleClear();
|
||||
}
|
||||
}}
|
||||
tabIndex="0"
|
||||
>
|
||||
<SolidIcons name="removerectangle" width="20" fill="#ACB2B9" />
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
filteredParams?.length > 0 && (
|
||||
<div className={`${type === 'request' ? 'request-body' : type}-fields d-flex`}>
|
||||
<h5 className="text-heading form-label">{label}</h5>
|
||||
<div className="flex-grow-1 input-group-parent-container">
|
||||
{filteredParams.map((param) => (
|
||||
<div className="input-group-wrapper" key={type === 'request' ? param : param.name}>
|
||||
<div className="input-group">
|
||||
{paramDetails(param)}
|
||||
<div className="col field overflow-hidden code-hinter-borderless">{inputField(param)}</div>
|
||||
{((type === 'request' && options['params'][type][param]) || options['params'][type][param.name]) &&
|
||||
clearButton(param)}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
RenderParameterFields.propTypes = {
|
||||
parameters: PropTypes.any,
|
||||
type: PropTypes.string,
|
||||
label: PropTypes.string,
|
||||
options: PropTypes.object,
|
||||
changeParam: PropTypes.func,
|
||||
removeParam: PropTypes.func,
|
||||
darkMode: PropTypes.bool,
|
||||
};
|
||||
|
|
@ -13,6 +13,7 @@ import CodeHinter from '@/AppBuilder/CodeEditor';
|
|||
import GoogleSheets from '@/_components/Googlesheets';
|
||||
import Slack from '@/_components/Slack';
|
||||
import Zendesk from '@/_components/Zendesk';
|
||||
import ApiEndpointInput from '@/_components/ApiEndpointInput';
|
||||
import { ConditionFilter, CondtionSort, MultiColumn } from '@/_components/MultiConditions';
|
||||
import Salesforce from '@/_components/Salesforce';
|
||||
import ToolJetDbOperations from '@/AppBuilder/QueryManager/QueryEditors/TooljetDatabase/ToolJetDbOperations';
|
||||
|
|
@ -219,6 +220,8 @@ const DynamicForm = ({
|
|||
return ConditionFilter;
|
||||
case 'sorts':
|
||||
return CondtionSort;
|
||||
case 'react-component-api-endpoint':
|
||||
return ApiEndpointInput;
|
||||
case 'react-component-salesforce':
|
||||
return Salesforce;
|
||||
case 'react-component-sharepoint':
|
||||
|
|
@ -255,6 +258,7 @@ const DynamicForm = ({
|
|||
encrypted,
|
||||
placeholders = {},
|
||||
editorType = 'basic',
|
||||
specUrl = '',
|
||||
disabled = false,
|
||||
buttonText,
|
||||
text,
|
||||
|
|
@ -416,7 +420,15 @@ const DynamicForm = ({
|
|||
darkMode,
|
||||
optionsChanged,
|
||||
};
|
||||
case 'codehinter':
|
||||
case 'codehinter': {
|
||||
let theme;
|
||||
if (darkMode) {
|
||||
theme = 'monokai';
|
||||
} else if (lineNumbers) {
|
||||
theme = 'duotone-light';
|
||||
} else {
|
||||
theme = 'default';
|
||||
}
|
||||
return {
|
||||
type: editorType,
|
||||
initialValue: options[key]
|
||||
|
|
@ -428,6 +440,7 @@ const DynamicForm = ({
|
|||
lineNumbers,
|
||||
className: className ? className : lineNumbers ? 'query-hinter' : 'codehinter-query-editor-input',
|
||||
onChange: (value) => optionchanged(key, value),
|
||||
theme: theme,
|
||||
placeholder,
|
||||
height,
|
||||
width,
|
||||
|
|
@ -436,6 +449,7 @@ const DynamicForm = ({
|
|||
disabled,
|
||||
delayOnChange: false,
|
||||
};
|
||||
}
|
||||
case 'react-component-openapi-validator':
|
||||
return {
|
||||
format: options.format?.value,
|
||||
|
|
@ -483,7 +497,13 @@ const DynamicForm = ({
|
|||
onChange: (value) => optionchanged(key, value),
|
||||
placeholders,
|
||||
};
|
||||
|
||||
case 'react-component-api-endpoint':
|
||||
return {
|
||||
specUrl: specUrl,
|
||||
optionsChanged,
|
||||
options,
|
||||
darkMode,
|
||||
};
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
|
|
@ -556,7 +576,8 @@ const DynamicForm = ({
|
|||
{Object.keys(obj).map((key) => {
|
||||
const { label, type, encrypted, className, key: propertyKey } = obj[key];
|
||||
const Element = getElement(type);
|
||||
const isSpecificComponent = ['tooljetdb-operations'].includes(type);
|
||||
const isSpecificComponent = ['tooljetdb-operations', 'react-component-api-endpoint'].includes(type);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cx('my-2', {
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ export const OrganizationList = function () {
|
|||
<div className={`align-items-center d-flex tj-org-dropdown ${darkMode && 'dark-theme'}`}>
|
||||
{org.id === current_organization_id ? (
|
||||
<div className="current-org-avatar">
|
||||
<SolidIcon name="tick" fill="#3E63DD" dataCy="add-new-workspace-link" width="20" viewBox="0 0 17 15" />
|
||||
<SolidIcon name="tick" fill="#3E63DD" data-cy="add-new-workspace-link" width="20" viewBox="0 0 17 15" />
|
||||
</div>
|
||||
) : (
|
||||
<div
|
||||
|
|
@ -79,7 +79,7 @@ export const OrganizationList = function () {
|
|||
data-cy="current-org-indicator"
|
||||
onClick={() => setShowEditOrg(true)}
|
||||
>
|
||||
<SolidIcon name="editable" fill="#3E63DD" dataCy="add-new-workspace-link" width="16" />
|
||||
<SolidIcon name="editable" fill="#3E63DD" data-cy="edit-rectangle-icon" width="16" />
|
||||
</div>
|
||||
</ToolTip>
|
||||
) : (
|
||||
|
|
|
|||
|
|
@ -1474,5 +1474,6 @@ export const checkConditionsForRoute = (conditions, conditionsObj) => {
|
|||
};
|
||||
|
||||
export const hasBuilderRole = (roleObj) => {
|
||||
return roleObj.name === 'builder';
|
||||
if (roleObj.name) return roleObj.name === 'builder';
|
||||
return false;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -228,7 +228,7 @@
|
|||
|
||||
.datasource-card {
|
||||
height: 30px;
|
||||
height: 122px !important;
|
||||
height: 160px !important;
|
||||
|
||||
button {
|
||||
display: none;
|
||||
|
|
@ -307,6 +307,7 @@
|
|||
.add-plugin-card{
|
||||
border: 1px dashed var(--border-default, #CCD1D5);
|
||||
background-color: var(--interactive-weak);
|
||||
height: 160px;
|
||||
|
||||
&:hover{
|
||||
border: 1px dashed var(--border-strong, #CCD1D5);
|
||||
|
|
@ -334,4 +335,36 @@
|
|||
background-color: var(--interactive-default);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.card-tag{
|
||||
position: relative;
|
||||
left: 85px;
|
||||
bottom: 10px;
|
||||
}
|
||||
|
||||
.tag{
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
padding: 1px 7px;
|
||||
width: 38px;
|
||||
height: 18px;
|
||||
background: linear-gradient(271.34deg, rgba(255, 95, 109, 0.12) -88.47%, rgba(255, 195, 113, 0.12) 94.89%);
|
||||
border-radius: 100px;
|
||||
|
||||
.p{
|
||||
background: linear-gradient(96.1deg, #FF5F6D -15.44%, #FFC371 99.37%);
|
||||
}
|
||||
}
|
||||
|
||||
.ee-gradient-text {
|
||||
background: linear-gradient(96.1deg, #FF5F6D -15.44%, #FFC371 99.37%);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
font-size: 11px;
|
||||
font-weight: 500;
|
||||
line-height: 16px;
|
||||
margin-top: 0px;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -814,6 +814,16 @@ $border-radius: 4px;
|
|||
overflow: hidden;
|
||||
|
||||
.input-group {
|
||||
.code-hinter-borderless {
|
||||
.code-hinter-wrapper {
|
||||
border-right-width: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.code-hinter-clear-btn {
|
||||
padding: 5px 10px 5px 6px;
|
||||
}
|
||||
|
||||
.field {
|
||||
.form-control {
|
||||
height: 32px;
|
||||
|
|
@ -825,6 +835,12 @@ $border-radius: 4px;
|
|||
line-height: 20px;
|
||||
}
|
||||
|
||||
.form-control-underline {
|
||||
text-decoration: underline;
|
||||
text-decoration-style: dashed;
|
||||
text-underline-offset: 2.5px;
|
||||
}
|
||||
|
||||
.code-hinter-col {
|
||||
margin-bottom: 0 !important;
|
||||
|
||||
|
|
|
|||
|
|
@ -7012,6 +7012,25 @@ input.hide-input-arrows {
|
|||
}
|
||||
}
|
||||
|
||||
.filter-header{
|
||||
width: 100%;
|
||||
height: 56px;
|
||||
padding: 0 24px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
color: var(--text-default);
|
||||
border-bottom: 1px solid var(--border-weak);
|
||||
|
||||
.filter-heading{
|
||||
font-family: IBM Plex Sans;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
line-height: 20px;
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
|
||||
tbody {
|
||||
width: 100% !important;
|
||||
flex-grow: 1;
|
||||
|
|
@ -7869,6 +7888,7 @@ tbody {
|
|||
border-right: 1px solid var(--slate5) !important;
|
||||
display: grid !important;
|
||||
grid-template-rows: auto 1fr auto !important;
|
||||
position: fixed;
|
||||
}
|
||||
|
||||
.home-page-sidebar {
|
||||
|
|
@ -10410,6 +10430,7 @@ tbody {
|
|||
.tj-db-filter-btn {
|
||||
width: 100%;
|
||||
height: 28px;
|
||||
display: flex;
|
||||
border-radius: 6px;
|
||||
background: transparent;
|
||||
color: var(--slate12);
|
||||
|
|
@ -10431,6 +10452,20 @@ tbody {
|
|||
border-radius: 6px !important;
|
||||
}
|
||||
|
||||
.tj-db-filter-btn-applied,
|
||||
.tj-db-filter-clear-icon{
|
||||
background-color: var(--indigo4) !important;
|
||||
color: var(--indigo9) !important;
|
||||
|
||||
&:hover{
|
||||
background-color: var(--button-secondary-pressed) !important;
|
||||
}
|
||||
}
|
||||
|
||||
.tj-db-filter-clear-icon{
|
||||
border-radius: 0px 6px 6px 0px;
|
||||
}
|
||||
|
||||
.tj-db-filter-btn-active,
|
||||
.tj-db-sort-btn-active {
|
||||
display: flex !important;
|
||||
|
|
@ -10444,6 +10479,23 @@ tbody {
|
|||
color: var(--indigo9) !important;
|
||||
}
|
||||
|
||||
.tj-db-filter-btn-active{
|
||||
background: var(--button-outline-pressed) !important;
|
||||
color: var(--text-default) !important;
|
||||
}
|
||||
|
||||
.tj-db-filter-btn-active-filter{
|
||||
display: flex !important;
|
||||
flex-direction: row !important;
|
||||
justify-content: center !important;
|
||||
align-items: center !important;
|
||||
width: 100% !important;
|
||||
height: 28px !important;
|
||||
border-radius: 6px !important;
|
||||
background: var(--button-secondary-pressed) !important;
|
||||
color: var(--text-brand) !important;
|
||||
}
|
||||
|
||||
.tj-db-header-add-new-row-btn {
|
||||
height: 28px;
|
||||
background: transparent;
|
||||
|
|
@ -13076,6 +13128,26 @@ color: var(--text-default);
|
|||
}
|
||||
}
|
||||
|
||||
.tag-container{
|
||||
width: 38px;
|
||||
height: 18px;
|
||||
background: linear-gradient(271.34deg, rgba(255, 95, 109, 0.12) -88.47%, rgba(255, 195, 113, 0.12) 94.89%);
|
||||
border-radius: 100px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 1px 7px;
|
||||
|
||||
span{
|
||||
font-size: 11px;
|
||||
line-height: 16px;
|
||||
font-weight: 500;
|
||||
background: linear-gradient(96.1deg, #FF5F6D -15.44%, #FFC371 99.37%);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
.template-source-name {
|
||||
color: var(--slate12) !important;
|
||||
}
|
||||
|
|
@ -16027,7 +16099,7 @@ color: var(--text-default);
|
|||
}
|
||||
}
|
||||
|
||||
div.ds-svg-container svg {
|
||||
div.ds-svg-container img {
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
|
|
|
|||
12
frontend/src/_ui/AiBanner.jsx
Normal file
12
frontend/src/_ui/AiBanner.jsx
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
import React from 'react';
|
||||
import Icon from '@/_ui/Icon/SolidIcons';
|
||||
function AiBanner({ className }) {
|
||||
return (
|
||||
<div className={`d-flex tag ${className}`}>
|
||||
<Icon name="AI-tag" />
|
||||
<p className="ee-gradient-text">AI</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default AiBanner;
|
||||
|
|
@ -105,6 +105,11 @@
|
|||
background: var(--indigo9);
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
background: var(--button-primary-disabled) !important;
|
||||
color: var(--text-disabled-on-solid) !important;
|
||||
border: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.tj-zBlack-btn {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import React from 'react';
|
||||
// eslint-disable-next-line import/no-unresolved
|
||||
import { allSvgs } from '@tooljet/plugins/client';
|
||||
import AiBanner from '@/_ui/AiBanner';
|
||||
|
||||
const Card = ({
|
||||
title,
|
||||
|
|
@ -13,6 +14,7 @@ const Card = ({
|
|||
titleClassName,
|
||||
actionButton,
|
||||
darkMode,
|
||||
tags = [],
|
||||
}) => {
|
||||
const DisplayIcon = ({ src }) => {
|
||||
if (typeof src !== 'string') return;
|
||||
|
|
@ -44,7 +46,8 @@ const Card = ({
|
|||
data-cy={`data-source-${String(title).toLocaleLowerCase()}`}
|
||||
>
|
||||
<div className="card-body">
|
||||
<center>
|
||||
{tags && tags.includes('AI') && <AiBanner className="card-tag" />}
|
||||
<center style={{ marginTop: tags.length > 0 ? '0px' : '15px' }}>
|
||||
<DisplayIcon src={src} />
|
||||
<br></br>
|
||||
<br></br>
|
||||
|
|
|
|||
34
frontend/src/_ui/Icon/solidIcons/AITag.jsx
Normal file
34
frontend/src/_ui/Icon/solidIcons/AITag.jsx
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
import React from 'react';
|
||||
|
||||
const AITag = ({ fill = 'none', width = '12', height = '12', className = '', viewBox = '0 0 12 12' }) => {
|
||||
return (
|
||||
<svg
|
||||
width={width}
|
||||
height={height}
|
||||
fill={fill}
|
||||
className={className}
|
||||
viewBox={viewBox}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M1.36783 5.99998C4.31182 7.02317 5.28234 8.16244 5.99999 11C6.71764 8.16244 7.68814 7.02317 10.6321 5.99998C7.68814 4.97686 6.71764 3.83759 5.99999 1C5.28234 3.83759 4.31182 4.97686 1.36783 5.99998Z"
|
||||
fill="url(#paint0_linear_654_1335)"
|
||||
/>
|
||||
<defs>
|
||||
<linearGradient
|
||||
id="paint0_linear_654_1335"
|
||||
x1="11.5717"
|
||||
y1="-5.5"
|
||||
x2="-0.0865091"
|
||||
y2="-4.34623"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop stopColor="#FF5F6D" />
|
||||
<stop offset="1" stopColor="#FFC371" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
export default AITag;
|
||||
|
|
@ -174,6 +174,7 @@ import Search01 from './Search01.jsx';
|
|||
import ShiftButtonIcon from './ShiftButtonIcon.jsx';
|
||||
import Unpin01 from './Unpin01.jsx';
|
||||
import WarningUserNotFound from './WarningUserNotFound.jsx';
|
||||
import AITag from './AITag.jsx';
|
||||
import Reset from './Reset.jsx';
|
||||
|
||||
const Icon = (props) => {
|
||||
|
|
@ -530,6 +531,8 @@ const Icon = (props) => {
|
|||
return <TriangleUpCenter {...props} />;
|
||||
case 'TriangleDownCenter':
|
||||
return <TriangleDownCenter {...props} />;
|
||||
case 'AI-tag':
|
||||
return <AITag {...props} />;
|
||||
default:
|
||||
return <Apps {...props} />;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,9 +29,10 @@ export const SelectComponent = ({
|
|||
menuPlacement = 'auto',
|
||||
useCustomStyles = false,
|
||||
isDisabled = false,
|
||||
borderRadius,
|
||||
} = restProps;
|
||||
|
||||
const customStyles = useCustomStyles ? styles : defaultStyles(isDarkMode, width, height, styles);
|
||||
const customStyles = useCustomStyles ? styles : defaultStyles(isDarkMode, width, height, styles, borderRadius);
|
||||
const selectOptions =
|
||||
Array.isArray(options) && options.length === 0
|
||||
? options
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/* eslint-disable no-unused-vars */
|
||||
export default function styles(darkMode, width = 224, height = 32, styles = {}) {
|
||||
export default function styles(darkMode, width = 224, height = 32, styles = {}, borderRadius) {
|
||||
return {
|
||||
container: (provided) => ({
|
||||
...provided,
|
||||
|
|
@ -26,6 +26,7 @@ export default function styles(darkMode, width = 224, height = 32, styles = {})
|
|||
height: height,
|
||||
minHeight: height,
|
||||
cursor: styles.cursor ?? 'pointer',
|
||||
...(borderRadius ? { borderRadius } : {}),
|
||||
}),
|
||||
valueContainer: (provided, state) => ({
|
||||
...provided,
|
||||
|
|
|
|||
|
|
@ -21,8 +21,12 @@ const ForgotPasswordInfoScreen = ({ email }) => {
|
|||
<div className="forgot-password-info-wrapper info-screen">
|
||||
<OnboardingUIWrapper>
|
||||
<FormHeader>{t('forgotPasswordInfo.header', 'Check your mail')}</FormHeader>
|
||||
<p className="message">{message}</p>
|
||||
<span className="info">{info}</span>
|
||||
<p className="message" data-cy="onboarding-page-description">
|
||||
{message}
|
||||
</p>
|
||||
<span className="info" data-cy="info-message">
|
||||
{info}
|
||||
</span>
|
||||
<SepratorComponent />
|
||||
<div className="action-buttons">
|
||||
<button onClick={() => navigate('/login')} className="back-to-login-button" data-cy="back-to-login">
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@ const LoginForm = ({
|
|||
<>
|
||||
{' '}
|
||||
{signupText}{' '}
|
||||
<Link to={signUpUrl} className="signin-link" tabIndex="-1" data-cy="signin-link">
|
||||
<Link to={signUpUrl} className="signin-link" tabIndex="-1" data-cy="create-an-account-link">
|
||||
{t('createToolJetAccount', signUpCTA)}
|
||||
</Link>
|
||||
</>
|
||||
|
|
|
|||
|
|
@ -17,7 +17,9 @@ const ForgotPasswordInfoScreen = ({ email }) => {
|
|||
<div className="forgot-password-info-wrapper info-screen">
|
||||
<OnboardingUIWrapper>
|
||||
<FormHeader>Password has been reset</FormHeader>
|
||||
<p className="message">{message}</p>
|
||||
<p className="message" data-cy="reset-password-page-description">
|
||||
{message}
|
||||
</p>
|
||||
<div className="action-buttons pt-3">
|
||||
<button
|
||||
onClick={() =>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,9 @@ import './resources/styles/form-description.styles.scss';
|
|||
const FormDescription = ({ children: View }) => {
|
||||
return (
|
||||
<>
|
||||
<p className="onboarding-form-description">{View}</p>
|
||||
<p className="onboarding-form-description" data-cy="onboarding-page-description">
|
||||
{View}
|
||||
</p>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
import React from 'react';
|
||||
|
||||
const FormHeader = ({ children: View, styles, dataCy }) => {
|
||||
const defaultDataCy = View?.toString()?.toLowerCase().replace(/\s+/g, '-');
|
||||
const computedDataCy = dataCy || defaultDataCy;
|
||||
|
||||
return (
|
||||
<>
|
||||
<h2 className="form-header" style={styles} data-cy={dataCy}>
|
||||
{View}
|
||||
</h2>
|
||||
</>
|
||||
<h2 className="form-header" style={styles} data-cy={`${computedDataCy}-header`}>
|
||||
{View}
|
||||
</h2>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue