diff --git a/.all-contributorsrc b/.all-contributorsrc index 7de94c9829..e520eaf64e 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -410,6 +410,16 @@ "code", "bug" ] + }, + { + "login": "pallavagarwal07", + "name": "Pallav Agarwal", + "avatar_url": "https://avatars.githubusercontent.com/u/9394044?v=4", + "profile": "https://www.varstack.com", + "contributions": [ + "code", + "bug" + ] } ], "contributorsPerLine": 7, diff --git a/.github/config.json b/.github/config.json index ec210a075b..2b52d79ad8 100644 --- a/.github/config.json +++ b/.github/config.json @@ -1 +1 @@ -{"runners":[{"versioning":{"source":"milestones","type":"SemVer"},"prereleaseName":"alpha","issue":{"labels":{"Team Managers Pod":{"conditions":[{"label":"Login / Signup","type":"hasLabel","value":true},{"label":"Settings","type":"hasLabel","value":true},{"label":"Git Version Control","type":"hasLabel","value":true},{"label":"Home Page","type":"hasLabel","value":true},{"label":"Import-Export-App","type":"hasLabel","value":true},{"label":"advanced","type":"hasLabel","value":true},{"label":"Team Managers Pod","type":"hasLabel","value":true},{"label":"Invite users","type":"hasLabel","value":true},{"label":"ACL","type":"hasLabel","value":true},{"label":"Realtime Commenting","type":"hasLabel","value":true},{"label":"SSO","type":"hasLabel","value":true},{"label":"Multi User Realtime","type":"hasLabel","value":true}],"requires":1},"New Developers Pod":{"conditions":[{"label":"Deployment","type":"hasLabel","value":true},{"label":"Fork App","type":"hasLabel","value":true},{"label":"Omnibar","type":"hasLabel","value":true},{"label":"Onboarding","type":"hasLabel","value":true},{"label":"Telemetry","type":"hasLabel","value":true},{"label":"Entity Explorer","type":"hasLabel","value":true},{"label":"Generate Page","type":"hasLabel","value":true},{"label":"IDE","type":"hasLabel","value":true},{"label":"In App Comms","type":"hasLabel","value":true},{"label":"New Developers Pod","type":"hasLabel","value":true},{"label":"Sniping Mode","type":"hasLabel","value":true},{"label":"Design System","type":"hasLabel","value":true},{"label":"Example Apps","type":"hasLabel","value":true},{"label":"i18n","type":"hasLabel","value":true},{"label":"Super Admin","type":"hasLabel","value":true},{"label":"K8s","type":"hasLabel","value":true},{"label":"Docker","type":"hasLabel","value":true},{"label":"Welcome Screen","type":"hasLabel","value":true},{"label":"Templates","type":"hasLabel","value":true}],"requires":1},"BE Coders Pod":{"conditions":[{"label":"Datasources","type":"hasLabel","value":true},{"label":"Firestore","type":"hasLabel","value":true},{"label":"Google Sheets","type":"hasLabel","value":true},{"label":"Mongo","type":"hasLabel","value":true},{"label":"MySQL","type":"hasLabel","value":true},{"label":"Redshift","type":"hasLabel","value":true},{"label":"UQI","type":"hasLabel","value":true},{"label":"Query Editor","type":"hasLabel","value":true},{"label":"API pane","type":"hasLabel","value":true},{"label":"snowflake","type":"hasLabel","value":true},{"label":"S3","type":"hasLabel","value":true},{"label":"BE Coders Pod","type":"hasLabel","value":true},{"label":"Redis","type":"hasLabel","value":true},{"label":"New Datasource","type":"hasLabel","value":true},{"label":"Query Execution","type":"hasLabel","value":true},{"label":"Postgres","type":"hasLabel","value":true},{"label":"REST API plugin","type":"hasLabel","value":true},{"label":"SAAS Plugins","type":"hasLabel","value":true},{"label":"UQI components","type":"hasLabel","value":true},{"label":"UQI validations","type":"hasLabel","value":true},{"label":"Action form","type":"hasLabel","value":true},{"label":"UQI migration","type":"hasLabel","value":true},{"label":"SQL","type":"hasLabel","value":true},{"label":"Query Templates","type":"hasLabel","value":true},{"label":"Plugin Development","type":"hasLabel","value":true}],"requires":1},"FE Coders Pod":{"conditions":[{"label":"JS Linting & Errors","type":"hasLabel","value":true},{"label":"JS Editor","type":"hasLabel","value":true},{"label":"Debugger","type":"hasLabel","value":true},{"label":"JS","type":"hasLabel","value":true},{"label":"JS Snippets","type":"hasLabel","value":true},{"label":"Autocomplete","type":"hasLabel","value":true},{"label":"FE Coders Pod","type":"hasLabel","value":true},{"label":"Evaluated Value","type":"hasLabel","value":true},{"label":"Slash Command","type":"hasLabel","value":true},{"label":"New JS Function","type":"hasLabel","value":true},{"label":"JS Promises","type":"hasLabel","value":true},{"label":"OnPageLoad","type":"hasLabel","value":true},{"label":"Function execution","type":"hasLabel","value":true},{"label":"JS Refactoring","type":"hasLabel","value":true},{"label":"JS Usability","type":"hasLabel","value":true}],"requires":1},"App Viewers Pod":{"conditions":[{"label":"Button Widget","type":"hasLabel","value":true},{"label":"Chart Widget","type":"hasLabel","value":true},{"label":"Checkbox Widget","type":"hasLabel","value":true},{"label":"Container Widget","type":"hasLabel","value":true},{"label":"Date Picker Widget","type":"hasLabel","value":true},{"label":"Select Widget","type":"hasLabel","value":true},{"label":"File Picker Widget","type":"hasLabel","value":true},{"label":"Form Widget","type":"hasLabel","value":true},{"label":"Image Widget","type":"hasLabel","value":true},{"label":"Input Widget","type":"hasLabel","value":true},{"label":"List Widget","type":"hasLabel","value":true},{"label":"MultiSelect Widget","type":"hasLabel","value":true},{"label":"Map Widget","type":"hasLabel","value":true},{"label":"Modal Widget","type":"hasLabel","value":true},{"label":"Radio Widget","type":"hasLabel","value":true},{"label":"Rich Text Editor Widget","type":"hasLabel","value":true},{"label":"Tab Widget","type":"hasLabel","value":true},{"label":"Table Widget","type":"hasLabel","value":true},{"label":"Text Widget","type":"hasLabel","value":true},{"label":"Video Widget","type":"hasLabel","value":true},{"label":"iFrame","type":"hasLabel","value":true},{"label":"Menu Button","type":"hasLabel","value":true},{"label":"Rating","type":"hasLabel","value":true},{"label":"Widget Validation","type":"hasLabel","value":true},{"label":"reallabel","type":"hasLabel","value":true},{"label":"New Widget","type":"hasLabel","value":true},{"label":"Switch widget","type":"hasLabel","value":true},{"label":"Widget Styling","type":"hasLabel","value":true},{"label":"Audio Widget","type":"hasLabel","value":true},{"label":"Icon Button Widget","type":"hasLabel","value":true},{"label":"Checkbox Group widget","type":"hasLabel","value":true},{"label":"Stat Box Widget","type":"hasLabel","value":true},{"label":"Voice Recorder Widget","type":"hasLabel","value":true},{"label":"Calendar Widget","type":"hasLabel","value":true},{"label":"Menu Button Widget","type":"hasLabel","value":true},{"label":"Divider Widget","type":"hasLabel","value":true},{"label":"Rating Widget","type":"hasLabel","value":true},{"label":"App Viewers Pod","type":"hasLabel","value":true},{"label":"App Navigation","type":"hasLabel","value":true},{"label":"View Mode","type":"hasLabel","value":true},{"label":"Embedding Apps","type":"hasLabel","value":true},{"label":"Widget Property","type":"hasLabel","value":true},{"label":"Document Viewer Widget","type":"hasLabel","value":true},{"label":"Radio Group Widget","type":"hasLabel","value":true},{"label":"Currency Input Widget","type":"hasLabel","value":true},{"label":"TreeSelect","type":"hasLabel","value":true},{"label":"MultiTree Select Widget","type":"hasLabel","value":true},{"label":"Phone Input Widget","type":"hasLabel","value":true},{"label":"JSON Form","type":"hasLabel","value":true},{"label":"All Widgets","type":"hasLabel","value":true},{"label":"App Theming","type":"hasLabel","value":true}],"requires":1},"UI Builders Pod":{"conditions":[{"label":"Property Pane","type":"hasLabel","value":true},{"label":"Pages","type":"hasLabel","value":true},{"label":"UI Builders Pod","type":"hasLabel","value":true},{"label":"Copy Paste","type":"hasLabel","value":true},{"label":"Drag & Drop","type":"hasLabel","value":true},{"label":"Undo/Redo","type":"hasLabel","value":true},{"label":"Responsive Viewport","type":"hasLabel","value":true},{"label":"Canvas Zoom","type":"hasLabel","value":true},{"label":"Widgets Pane","type":"hasLabel","value":true},{"label":"UI Performance","type":"hasLabel","value":true},{"label":"Widget Grouping","type":"hasLabel","value":true},{"label":"Reflow & Resize","type":"hasLabel","value":true}],"requires":1},"User Education Pod":{"conditions":[{"label":"Content","type":"hasLabel","value":true},{"label":"Documentation","type":"hasLabel","value":true}],"requires":1},"Platform Pod":{"conditions":[{"label":"Platform Pod","type":"hasLabel","value":true},{"label":"Team Managers Pod","type":"hasLabel","value":true},{"label":"New Developers Pod","type":"hasLabel","value":true}],"requires":1},"Actions Pod":{"conditions":[{"label":"FE Coders Pod","type":"hasLabel","value":true},{"label":"BE Coders Pod","type":"hasLabel","value":true}],"requires":1},"UI Building Pod":{"conditions":[{"label":"App Viewers Pod","type":"hasLabel","value":true},{"label":"UI Builders Pod","type":"hasLabel","value":true}],"requires":1}}},"root":"."}],"labels":{"Tab Widget":{"color":"e2c76c","name":"Tab Widget","description":""},"Dont merge":{"color":"ADB39C","name":"Dont merge","description":""},"Epic":{"color":"3E4B9E","name":"Epic","description":"A zenhub epic that describes a project"},"Menu Button Widget":{"color":"235708","name":"Menu Button Widget","description":"Issues related to Menu Button widget"},"advanced":{"color":"5f4115","name":"advanced","description":"Features aimed at advanced users"},"Checkbox Group widget":{"color":"D2ACD2","name":"Checkbox Group widget","description":"Issues related to Checkbox Group Widget"},"Input Widget":{"color":"ae65d8","name":"Input Widget","description":""},"Security":{"color":"99139C","name":"Security","description":""},"QA":{"color":"e2ca68","name":"QA","description":""},"Verified":{"color":"9bf416","name":"Verified","description":""},"Wont Fix":{"color":"ffffff","name":"Wont Fix","description":"This will not be worked on"},"MySQL":{"color":"B0F9F4","name":"MySQL","description":""},"Development":{"color":"9F8A02","name":"Development","description":""},"Help Wanted":{"color":"008672","name":"Help Wanted","description":"Extra attention is needed"},"Home Page":{"color":"9c0c8e","name":"Home Page","description":"Issues related to the application home page"},"Rating Widget":{"color":"235708","name":"Rating Widget","description":"Issues related to the rating widget"},"Stat Box Widget":{"color":"f1c9ce","name":"Stat Box Widget","description":"Issues related to stat box"},"Enhancement":{"color":"a2eeef","name":"Enhancement","description":"New feature or request"},"Settings":{"color":"f7ff60","name":"Settings","description":"organization, team & user settings"},"Fork App":{"color":"5369db","name":"Fork App","description":"Issues related to forking apps"},"Container Widget":{"color":"19AD0D","name":"Container Widget","description":"Container widget"},"Papercut":{"color":"B562F6","name":"Papercut","description":""},"community":{"color":"dded34","name":"community","description":"issues reported by community members"},"Needs Design":{"color":"bfd4f2","name":"Needs Design","description":"needs design or changes to design"},"UQI":{"color":"FB8E9C","name":"UQI","description":""},"AutomationGap":{"color":"ed13bb","name":"AutomationGap","description":"Issues that needs automated tests"},"i18n":{"color":"1799b0","name":"i18n","description":"Represents issues that need to be tackled to handle internationalization"},"Rich Text Editor Widget":{"color":"f72cac","name":"Rich Text Editor Widget","description":""},"Onboarding":{"color":"d5794b","name":"Onboarding","description":"Issues related to onboarding new developers"},"Pages":{"color":"d7fd80","name":"Pages","description":"Issues related to configuring pages"},"skip-changelog":{"color":"06086F","name":"skip-changelog","description":"Adding this label to a PR prevents it from being listed in the changelog"},"Low":{"color":"79e53b","name":"Low","description":"An issue that is neither critical nor breaks a user flow"},"potential-duplicate":{"color":"d3cb2e","name":"potential-duplicate","description":"This label marks issues that are potential duplicates of already open issues"},"Audio Widget":{"color":"447B9A","name":"Audio Widget","description":"Issues related to Audio Widget"},"Firestore":{"color":"F1C2DF","name":"Firestore","description":"Issues related to the firestore Integration"},"New Widget":{"color":"be4cf2","name":"New Widget","description":"A request for a new widget"},"Performance":{"color":"d30e53","name":"Performance","description":"Page Load and evaluations"},"Modal Widget":{"color":"03846f","name":"Modal Widget","description":""},"UX Improvement":{"color":"f4a089","name":"UX Improvement","description":""},"S3":{"color":"c57928","name":"S3","description":"Issues related to the S3 plugin"},"Release Blocker":{"color":"5756bf","name":"Release Blocker","description":"This issue must be resolved before the release"},"safari":{"color":"51C6AA","name":"safari","description":"Bugs seen on safari browser"},"Example Apps":{"color":"1799b0","name":"Example Apps","description":"Example apps created for new signups"},"MultiSelect Widget":{"color":"AB62D4","name":"MultiSelect Widget","description":"Issues related to MultiSelect Widget"},"JS Editor":{"color":"48b992","name":"JS Editor","description":"Issues related to JS Editor"},"Widget Styling":{"color":"37EA75","name":"Widget Styling","description":"all about widget styling"},"Calendar Widget":{"color":"8c6644","name":"Calendar Widget","description":""},"JS":{"color":"e46785","name":"JS","description":"Issues related to JS on the platform"},"Website":{"color":"151720","name":"Website","description":"Related to www.appsmith.com website"},"Low effort":{"color":"8B59F0","name":"Low effort","description":"Something that'll take a few days to build"},"App Viewers Pod":{"color":"cd8ef9","name":"App Viewers Pod","description":"This label assigns issues to the app viewers pod"},"Checkbox Widget":{"color":"074ac6","name":"Checkbox Widget","description":""},"Spam":{"color":"620faf","name":"Spam","description":""},"Voice Recorder Widget":{"color":"85bc87","name":"Voice Recorder Widget","description":""},"Select Widget":{"color":"0c669e","name":"Select Widget","description":"Select or dropdown widget"},"Bug":{"color":"d73a4a","name":"Bug","description":"Something isn't working"},"Widget Validation":{"color":"6990BC","name":"Widget Validation","description":"Issues related to widget property validation"},"Generate Page":{"color":"f14274","name":"Generate Page","description":"Issures related to page generation"},"File Picker Widget":{"color":"6ae4f2","name":"File Picker Widget","description":""},"snowflake":{"color":"47075c","name":"snowflake","description":"Issues related to the snowflake Integration"},"Automation":{"color":"CCAF60","name":"Automation","description":""},"hotfix":{"color":"BA3F1D","name":"hotfix","description":""},"Team Managers Pod":{"color":"bddb81","name":"Team Managers Pod","description":"Issues that team managers care about for the security and efficiency of their teams"},"API pane":{"color":"e417c7","name":"API pane","description":"API configuration section"},"Import-Export-App":{"color":"a7768a","name":"Import-Export-App","description":"Issues related to importing and exporting apps"},"High effort":{"color":"A7E87B","name":"High effort","description":"Something that'll take more than a month to build"},"ACL":{"color":"747224","name":"ACL","description":"User permissions and access controls"},"Telemetry":{"color":"bc70f9","name":"Telemetry","description":"Issues related to instrumenting appsmith"},"Radio Widget":{"color":"91ef15","name":"Radio Widget","description":""},"Omnibar":{"color":"10b5ce","name":"Omnibar","description":"Issues related to the omnibar for navigation"},"Button Widget":{"color":"34efae","name":"Button Widget","description":""},"Switch widget":{"color":"33A8CE","name":"Switch widget","description":"The switch widget"},"Map Widget":{"color":"7eef7a","name":"Map Widget","description":""},"UI Building Pod":{"color":"e2ffb2","name":"UI Building Pod","description":""},"Task":{"color":"085630","name":"Task","description":"A simple Todo"},"Design System":{"color":"12b715","name":"Design System","description":"Design system"},"opera":{"color":"C63F5B","name":"opera","description":"Any issues identified on the opera browser"},"Login / Signup":{"color":"949fe0","name":"Login / Signup","description":"Authentication flows"},"Image Widget":{"color":"8de8ad","name":"Image Widget","description":""},"firefox":{"color":"6d56e2","name":"firefox","description":""},"Property Pane":{"color":"b356ff","name":"Property Pane","description":"Issues related to the behaviour of the property pane"},"Deployment":{"color":"bdf989","name":"Deployment","description":"Installation process of appsmith"},"Critical":{"color":"9b1b28","name":"Critical","description":"This issue needs immediate attention. Drop everything else"},"IDE":{"color":"61b2ee","name":"IDE","description":"Issues related to the IDE"},"Production":{"color":"b60205","name":"Production","description":""},"Dependencies":{"color":"0366d6","name":"Dependencies","description":"Pull requests that update a dependency file"},"Actions Pod":{"color":"61ed84","name":"Actions Pod","description":"Issues picked up by the action pod"},"Google Sheets":{"color":"51D86A","name":"Google Sheets","description":"Issues related to Google Sheets"},"Icon Button Widget":{"color":"D319CE","name":"Icon Button Widget","description":"Issues related to the icon button widget"},"Mongo":{"color":"fef2c0","name":"Mongo","description":"Issues related to Mongo DB plugin"},"Documentation":{"color":"a8dff7","name":"Documentation","description":"Improvements or additions to documentation"},"TestGap":{"color":"f28253","name":"TestGap","description":"Issues identified for test plan improvement"},"keyboard shortcut":{"color":"0688B6","name":"keyboard shortcut","description":""},"Git Version Control":{"color":"C4568E","name":"Git Version Control","description":"Issues related to version control"},"Reopen":{"color":"897548","name":"Reopen","description":""},"Redshift":{"color":"ABAEB5","name":"Redshift","description":"Issues related to the redshift integration"},"Date Picker Widget":{"color":"ef1ce1","name":"Date Picker Widget","description":""},"Entity Explorer":{"color":"a2e2f9","name":"Entity Explorer","description":"Issues related to navigation using the entity explorer"},"JS Linting & Errors":{"color":"E56AA5","name":"JS Linting & Errors","description":"Issues related to JS Linting and errors"},"iFrame":{"color":"3CD1DB","name":"iFrame","description":"Issues related to iFrame"},"Stale":{"color":"ededed","name":"Stale","description":null},"Debugger":{"color":"e79062","name":"Debugger","description":"Issues related to the debugger"},"Quick effort":{"color":"95ED65","name":"Quick effort","description":"Something that'll take a few hours to build"},"Text Widget":{"color":"d130d1","name":"Text Widget","description":""},"Video Widget":{"color":"23dd4b","name":"Video Widget","description":""},"Datasources":{"color":"f285e1","name":"Datasources","description":"Issues related to configuring datasource on appsmith"},"error":{"color":"B66773","name":"error","description":"All issues connected to error messages"},"Form Widget":{"color":"09ed77","name":"Form Widget","description":""},"Needs Triaging":{"color":"e8b851","name":"Needs Triaging","description":"Needs attention from maintainers to triage"},"Query Editor":{"color":"8887af","name":"Query Editor","description":"The section where a user can write DB queries."},"Autocomplete":{"color":"235708","name":"Autocomplete","description":"Issues related to the autocomplete"},"hacktoberfest":{"color":"0052cc","name":"hacktoberfest","description":"All issues that can be solved by the community during Hacktoberfest"},"Medium effort":{"color":"D31156","name":"Medium effort","description":"Something that'll take more than a week but less than a month to build"},"Release":{"color":"57e5e0","name":"Release","description":""},"High":{"color":"c94d14","name":"High","description":"This issue blocks a user from building or impacts a lot of users"},"Platform Pod":{"color":"500B69","name":"Platform Pod","description":"All issues related to using the appsmith platform"},"UI Performance":{"color":"1799b0","name":"UI Performance","description":"Issues related to UI performance"},"UI Builders Pod":{"color":"517fba","name":"UI Builders Pod","description":"Issues that UI Builders face using appsmith"},"Deploy Preview":{"color":"bfdadc","name":"Deploy Preview","description":"Issues found in Deploy Preview"},"Needs Tests":{"color":"8ee263","name":"Needs Tests","description":"Needs automated tests to assert a feature/bug fix"},"Refactor":{"color":"B96662","name":"Refactor","description":"needs refactoring of code"},"Divider Widget":{"color":"235708","name":"Divider Widget","description":"Issues related to the divider widget"},"Table Widget":{"color":"2eead1","name":"Table Widget","description":""},"Needs More Info":{"color":"e54c10","name":"Needs More Info","description":"Needs additional information"},"Good First Issue":{"color":"7057ff","name":"Good First Issue","description":"Good for newcomers"},"UI Improvement":{"color":"9aeef4","name":"UI Improvement","description":""},"Backend":{"color":"d4c5f9","name":"Backend","description":"This marks the issue or pull request to reference server code"},"Frontend":{"color":"87c7f2","name":"Frontend","description":"This label marks the issue or pull request to reference client code"},"In App Comms":{"color":"9168f4","name":"In App Comms","description":"Issues around communication with appsmith instances"},"Chart Widget":{"color":"616ecc","name":"Chart Widget","description":""},"regression":{"color":"ffe5bc","name":"regression","description":""},"List Widget":{"color":"8508A0","name":"List Widget","description":"Issues related to the list widget"},"Duplicate":{"color":"cfd3d7","name":"Duplicate","description":"This issue or pull request already exists"},"High impact":{"color":"853A9F","name":"High impact","description":""},"JS Snippets":{"color":"8d62d2","name":"JS Snippets","description":"issues related to JS Snippets"},"Copy Paste":{"name":"Copy Paste","description":"Issues related to copy paste","color":"b4f0a9"},"Drag & Drop":{"name":"Drag & Drop","description":"Issues related to the drag & drop experience","color":"92115a"},"SQL":{"name":"SQL","description":"Issues related to SQL Datasources","color":"a1633e"},"BE Coders Pod":{"color":"5d9848","name":"BE Coders Pod","description":"Issues related to users writing code to fetch and update data"},"FE Coders Pod":{"color":"a7effc","name":"FE Coders Pod","description":"Issues related to users writing javascript in appsmith"},"New Developers Pod":{"color":"6310da","name":"New Developers Pod","description":"Issues that new developers face while exploring the IDE"},"Sniping Mode":{"name":"Sniping Mode","description":"Issues related to sniping mode","color":"6310da"},"Redis":{"name":"Redis","description":"Issues related to Redis","color":"8b19cc"},"New Datasource":{"color":"9c0cf7","name":"New Datasource","description":"Requests for new datasources"},"Query Execution":{"color":"9c0cf7","name":"Query Execution","description":"Issues related to API / Query execution"},"Evaluated Value":{"name":"Evaluated Value","description":"Issues related to evaluated values","color":"39f6e7"},"Undo/Redo":{"name":"Undo/Redo","description":"Issues related to undo/redo","color":"f25880"},"App Navigation":{"name":"App Navigation","description":"Issues related to the topbar navigation and configuring it","color":"12b715"},"Responsive Viewport":{"color":"12b715","name":"Responsive Viewport","description":"Issues seen on different viewports like mobile"},"Canvas Zoom":{"name":"Canvas Zoom","description":"Issues related to zooming the canvas","color":"57da0d"},"Widgets Pane":{"name":"Widgets Pane","description":"Issues related to the discovery and organisation of widgets","color":"ad5d78"},"Invite users":{"color":"1799b0","name":"Invite users","description":"Invite users flow and any associated actions"},"View Mode":{"color":"1799b0","name":"View Mode","description":"Issues related to the view mode"},"User Education Pod":{"name":"User Education Pod","description":"Issues related to user education","color":"1799b0"},"Content":{"name":"Content","description":"For content related topics i.e blogs, templates, videos","color":"a8dff7"},"Embedding Apps":{"name":"Embedding Apps","description":"Issues related to embedding","color":"849aff"},"Slash Command":{"name":"Slash Command","description":"Issues related to the slash command","color":"a0608e"},"Widget Property":{"name":"Widget Property","description":"Issues related to adding / modifying widget properties across widgets","color":"5e92cb"},"Windows":{"name":"Windows","description":"Issues related exclusively to Windows systems","color":"b4cb8a"},"Old App Issues":{"name":"Old App Issues","description":"Issues related to apps old apps a few weeks old and app issues in stale browser session","color":"87ab18"},"Document Viewer Widget":{"name":"Document Viewer Widget","description":"Issues related to Document Viewer Widget","color":"899d4b"},"Radio Group Widget":{"name":"Radio Group Widget","description":"Issues related to radio group widget","color":"b68495"},"Super Admin":{"name":"Super Admin","description":"Issues related to the super admin page","color":"b68495"},"Postgres":{"name":"Postgres","description":"Postgres related issues","color":"b68495"},"REST API plugin":{"name":"REST API plugin","description":"REST API plugin related issues","color":"9f538c"},"New JS Function":{"name":"New JS Function","description":"Issues related to adding a JS Function","color":"8e8aa4"},"Cannot Reproduce Issue":{"color":"93c9cc","name":"Cannot Reproduce Issue","description":"Issues that cannot be reproduced"},"Widget Grouping":{"name":"Widget Grouping","description":"Issues related to Widget Grouping","color":"a49951"},"K8s":{"name":"K8s","description":"Kubernetes related issues","color":"235b3b"},"Docker":{"name":"Docker","description":"Issues related to docker","color":"623a07"},"Camera Widget":{"name":"Camera Widget","description":"Issues and enhancements related to camera widget","color":"c7ace5"},"SAAS Plugins":{"name":"SAAS Plugins","description":"Issues related to SAAS Plugins","color":"ef9c9d"},"UQI components":{"name":"UQI components","description":"UQI specifically for components like sorting pagination and projection","color":"d7771f"},"UQI validations":{"name":"UQI validations","description":"validations for UQI datasources and action forms","color":"d7771f"},"Action form":{"name":"Action form","description":"Action forms for queries and API operations","color":"d7771f"},"UQI migration":{"name":"UQI migration","description":"migration of various datasources to uqi","color":"d7771f"},"JS Promises":{"name":"JS Promises","description":"Issues related to promises","color":"d7771f"},"OnPageLoad":{"name":"OnPageLoad","description":"OnPageLoad settings for JS functions","color":"63744e"},"Function execution":{"name":"Function execution","description":"JS function execution","color":"a302b0"},"JS Refactoring":{"name":"JS Refactoring","description":"cascading refactors to user JS due to user changes","color":"a302b0"},"JS Usability":{"name":"JS Usability","description":"usability issues with JS editor and JS elsewhere","color":"a302b0"},"Currency Input Widget":{"name":"Currency Input Widget","description":"Issues related to currency input widget","color":"b2164f"},"TreeSelect":{"name":"TreeSelect","description":"Issues related to TreeSelect Widget","color":"a1633e"},"MultiTree Select Widget":{"name":"MultiTree Select Widget","description":"Issues related to MultiTree Select Widget","color":"a1633e"},"Welcome Screen":{"name":"Welcome Screen","description":"Issues related to the welcome screen","color":"3897be"},"Query Templates":{"name":"Query Templates","description":"Issues related to query templates","color":"8f02d6"},"Realtime Commenting":{"color":"a70b86","name":"Realtime Commenting","description":"In-app communication between teams"},"Phone Input Widget":{"name":"Phone Input Widget","description":"Issues related to the Phone Input widget","color":"a70b86"},"JSON Form":{"name":"JSON Form","description":"Issue / features related to the JSON form wiget","color":"46b209"},"All Widgets":{"name":"All Widgets","description":"Issues related to all widgets","color":"972b36"},"V1":{"name":"V1","description":"V1","color":"67ab2e"},"Plugin Development":{"name":"Plugin Development","description":"Issues related to plugin development","color":"5e9d7b"},"Reflow & Resize":{"name":"Reflow & Resize","description":"All issues related to reflow and resize experience","color":"748a13"},"App Theming":{"name":"App Theming","description":"Items that are related to the App level theming controls epic","color":"8bf430"},"SSO":{"name":"SSO","description":"Issues, requests and enhancements around Single sign-on.","color":"bf019b"},"Multi User Realtime":{"name":"Multi User Realtime","description":"Issues related to multiple users using or editing an application","color":"e7b6ce"},"Templates":{"name":"Templates","description":"Issues related to Templates","color":"c3b541"},"Ready for design":{"name":"Ready for design","description":"this issue is ready for design: it contains clear problem statements and other required information","color":"ebf442"}}} \ No newline at end of file +{"runners":[{"versioning":{"source":"milestones","type":"SemVer"},"prereleaseName":"alpha","issue":{"labels":{"Team Managers Pod":{"conditions":[{"label":"Login / Signup","type":"hasLabel","value":true},{"label":"Settings","type":"hasLabel","value":true},{"label":"Git Version Control","type":"hasLabel","value":true},{"label":"Home Page","type":"hasLabel","value":true},{"label":"Import-Export-App","type":"hasLabel","value":true},{"label":"advanced","type":"hasLabel","value":true},{"label":"Team Managers Pod","type":"hasLabel","value":true},{"label":"Invite users","type":"hasLabel","value":true},{"label":"ACL","type":"hasLabel","value":true},{"label":"Realtime Commenting","type":"hasLabel","value":true},{"label":"SSO","type":"hasLabel","value":true},{"label":"Multi User Realtime","type":"hasLabel","value":true}],"requires":1},"New Developers Pod":{"conditions":[{"label":"Deployment","type":"hasLabel","value":true},{"label":"Fork App","type":"hasLabel","value":true},{"label":"Omnibar","type":"hasLabel","value":true},{"label":"Onboarding","type":"hasLabel","value":true},{"label":"Telemetry","type":"hasLabel","value":true},{"label":"Entity Explorer","type":"hasLabel","value":true},{"label":"Generate Page","type":"hasLabel","value":true},{"label":"IDE","type":"hasLabel","value":true},{"label":"In App Comms","type":"hasLabel","value":true},{"label":"New Developers Pod","type":"hasLabel","value":true},{"label":"Sniping Mode","type":"hasLabel","value":true},{"label":"Design System","type":"hasLabel","value":true},{"label":"Example Apps","type":"hasLabel","value":true},{"label":"i18n","type":"hasLabel","value":true},{"label":"Super Admin","type":"hasLabel","value":true},{"label":"K8s","type":"hasLabel","value":true},{"label":"Docker","type":"hasLabel","value":true},{"label":"Welcome Screen","type":"hasLabel","value":true},{"label":"Templates","type":"hasLabel","value":true}],"requires":1},"BE Coders Pod":{"conditions":[{"label":"Datasources","type":"hasLabel","value":true},{"label":"Firestore","type":"hasLabel","value":true},{"label":"Google Sheets","type":"hasLabel","value":true},{"label":"Mongo","type":"hasLabel","value":true},{"label":"MySQL","type":"hasLabel","value":true},{"label":"Redshift","type":"hasLabel","value":true},{"label":"UQI","type":"hasLabel","value":true},{"label":"Query Editor","type":"hasLabel","value":true},{"label":"API pane","type":"hasLabel","value":true},{"label":"snowflake","type":"hasLabel","value":true},{"label":"S3","type":"hasLabel","value":true},{"label":"BE Coders Pod","type":"hasLabel","value":true},{"label":"Redis","type":"hasLabel","value":true},{"label":"New Datasource","type":"hasLabel","value":true},{"label":"Query Execution","type":"hasLabel","value":true},{"label":"Postgres","type":"hasLabel","value":true},{"label":"REST API plugin","type":"hasLabel","value":true},{"label":"SAAS Plugins","type":"hasLabel","value":true},{"label":"UQI components","type":"hasLabel","value":true},{"label":"UQI validations","type":"hasLabel","value":true},{"label":"Action form","type":"hasLabel","value":true},{"label":"UQI migration","type":"hasLabel","value":true},{"label":"SQL","type":"hasLabel","value":true},{"label":"Query Templates","type":"hasLabel","value":true},{"label":"Plugin Development","type":"hasLabel","value":true}],"requires":1},"FE Coders Pod":{"conditions":[{"label":"JS Linting & Errors","type":"hasLabel","value":true},{"label":"JS Editor","type":"hasLabel","value":true},{"label":"Debugger","type":"hasLabel","value":true},{"label":"JS","type":"hasLabel","value":true},{"label":"JS Snippets","type":"hasLabel","value":true},{"label":"Autocomplete","type":"hasLabel","value":true},{"label":"FE Coders Pod","type":"hasLabel","value":true},{"label":"Evaluated Value","type":"hasLabel","value":true},{"label":"Slash Command","type":"hasLabel","value":true},{"label":"New JS Function","type":"hasLabel","value":true},{"label":"JS Promises","type":"hasLabel","value":true},{"label":"OnPageLoad","type":"hasLabel","value":true},{"label":"Function execution","type":"hasLabel","value":true},{"label":"JS Refactoring","type":"hasLabel","value":true},{"label":"JS Usability","type":"hasLabel","value":true}],"requires":1},"App Viewers Pod":{"conditions":[{"label":"Button Widget","type":"hasLabel","value":true},{"label":"Chart Widget","type":"hasLabel","value":true},{"label":"Checkbox Widget","type":"hasLabel","value":true},{"label":"Container Widget","type":"hasLabel","value":true},{"label":"Date Picker Widget","type":"hasLabel","value":true},{"label":"Select Widget","type":"hasLabel","value":true},{"label":"File Picker Widget","type":"hasLabel","value":true},{"label":"Form Widget","type":"hasLabel","value":true},{"label":"Image Widget","type":"hasLabel","value":true},{"label":"Input Widget","type":"hasLabel","value":true},{"label":"List Widget","type":"hasLabel","value":true},{"label":"MultiSelect Widget","type":"hasLabel","value":true},{"label":"Map Widget","type":"hasLabel","value":true},{"label":"Modal Widget","type":"hasLabel","value":true},{"label":"Radio Widget","type":"hasLabel","value":true},{"label":"Rich Text Editor Widget","type":"hasLabel","value":true},{"label":"Tab Widget","type":"hasLabel","value":true},{"label":"Table Widget","type":"hasLabel","value":true},{"label":"Text Widget","type":"hasLabel","value":true},{"label":"Video Widget","type":"hasLabel","value":true},{"label":"iFrame","type":"hasLabel","value":true},{"label":"Menu Button","type":"hasLabel","value":true},{"label":"Rating","type":"hasLabel","value":true},{"label":"Widget Validation","type":"hasLabel","value":true},{"label":"reallabel","type":"hasLabel","value":true},{"label":"New Widget","type":"hasLabel","value":true},{"label":"Switch widget","type":"hasLabel","value":true},{"label":"Widget Styling","type":"hasLabel","value":true},{"label":"Audio Widget","type":"hasLabel","value":true},{"label":"Icon Button Widget","type":"hasLabel","value":true},{"label":"Checkbox Group widget","type":"hasLabel","value":true},{"label":"Stat Box Widget","type":"hasLabel","value":true},{"label":"Voice Recorder Widget","type":"hasLabel","value":true},{"label":"Calendar Widget","type":"hasLabel","value":true},{"label":"Menu Button Widget","type":"hasLabel","value":true},{"label":"Divider Widget","type":"hasLabel","value":true},{"label":"Rating Widget","type":"hasLabel","value":true},{"label":"App Viewers Pod","type":"hasLabel","value":true},{"label":"App Navigation","type":"hasLabel","value":true},{"label":"View Mode","type":"hasLabel","value":true},{"label":"Embedding Apps","type":"hasLabel","value":true},{"label":"Widget Property","type":"hasLabel","value":true},{"label":"Document Viewer Widget","type":"hasLabel","value":true},{"label":"Radio Group Widget","type":"hasLabel","value":true},{"label":"Currency Input Widget","type":"hasLabel","value":true},{"label":"TreeSelect","type":"hasLabel","value":true},{"label":"MultiTree Select Widget","type":"hasLabel","value":true},{"label":"Phone Input Widget","type":"hasLabel","value":true},{"label":"JSON Form","type":"hasLabel","value":true},{"label":"All Widgets","type":"hasLabel","value":true},{"label":"App Theming","type":"hasLabel","value":true},{"label":"Button Group widget","type":"hasLabel","value":true}],"requires":1},"UI Builders Pod":{"conditions":[{"label":"Property Pane","type":"hasLabel","value":true},{"label":"Pages","type":"hasLabel","value":true},{"label":"UI Builders Pod","type":"hasLabel","value":true},{"label":"Copy Paste","type":"hasLabel","value":true},{"label":"Drag & Drop","type":"hasLabel","value":true},{"label":"Undo/Redo","type":"hasLabel","value":true},{"label":"Responsive Viewport","type":"hasLabel","value":true},{"label":"Canvas Zoom","type":"hasLabel","value":true},{"label":"Widgets Pane","type":"hasLabel","value":true},{"label":"UI Performance","type":"hasLabel","value":true},{"label":"Widget Grouping","type":"hasLabel","value":true},{"label":"Reflow & Resize","type":"hasLabel","value":true}],"requires":1},"User Education Pod":{"conditions":[{"label":"Content","type":"hasLabel","value":true},{"label":"Documentation","type":"hasLabel","value":true}],"requires":1},"Platform Pod":{"conditions":[{"label":"Platform Pod","type":"hasLabel","value":true},{"label":"Team Managers Pod","type":"hasLabel","value":true},{"label":"New Developers Pod","type":"hasLabel","value":true}],"requires":1},"Actions Pod":{"conditions":[{"label":"FE Coders Pod","type":"hasLabel","value":true},{"label":"BE Coders Pod","type":"hasLabel","value":true}],"requires":1},"UI Building Pod":{"conditions":[{"label":"App Viewers Pod","type":"hasLabel","value":true},{"label":"UI Builders Pod","type":"hasLabel","value":true}],"requires":1}}},"root":"."}],"labels":{"Tab Widget":{"color":"e2c76c","name":"Tab Widget","description":""},"Dont merge":{"color":"ADB39C","name":"Dont merge","description":""},"Epic":{"color":"3E4B9E","name":"Epic","description":"A zenhub epic that describes a project"},"Menu Button Widget":{"color":"235708","name":"Menu Button Widget","description":"Issues related to Menu Button widget"},"advanced":{"color":"5f4115","name":"advanced","description":"Features aimed at advanced users"},"Checkbox Group widget":{"color":"D2ACD2","name":"Checkbox Group widget","description":"Issues related to Checkbox Group Widget"},"Input Widget":{"color":"ae65d8","name":"Input Widget","description":""},"Security":{"color":"99139C","name":"Security","description":""},"QA":{"color":"e2ca68","name":"QA","description":""},"Verified":{"color":"9bf416","name":"Verified","description":""},"Wont Fix":{"color":"ffffff","name":"Wont Fix","description":"This will not be worked on"},"MySQL":{"color":"B0F9F4","name":"MySQL","description":""},"Development":{"color":"9F8A02","name":"Development","description":""},"Help Wanted":{"color":"008672","name":"Help Wanted","description":"Extra attention is needed"},"Home Page":{"color":"9c0c8e","name":"Home Page","description":"Issues related to the application home page"},"Rating Widget":{"color":"235708","name":"Rating Widget","description":"Issues related to the rating widget"},"Stat Box Widget":{"color":"f1c9ce","name":"Stat Box Widget","description":"Issues related to stat box"},"Enhancement":{"color":"a2eeef","name":"Enhancement","description":"New feature or request"},"Settings":{"color":"f7ff60","name":"Settings","description":"organization, team & user settings"},"Fork App":{"color":"5369db","name":"Fork App","description":"Issues related to forking apps"},"Container Widget":{"color":"19AD0D","name":"Container Widget","description":"Container widget"},"Papercut":{"color":"B562F6","name":"Papercut","description":""},"community":{"color":"dded34","name":"community","description":"issues reported by community members"},"Needs Design":{"color":"bfd4f2","name":"Needs Design","description":"needs design or changes to design"},"UQI":{"color":"FB8E9C","name":"UQI","description":""},"AutomationGap":{"color":"ed13bb","name":"AutomationGap","description":"Issues that needs automated tests"},"i18n":{"color":"1799b0","name":"i18n","description":"Represents issues that need to be tackled to handle internationalization"},"Rich Text Editor Widget":{"color":"f72cac","name":"Rich Text Editor Widget","description":""},"Onboarding":{"color":"d5794b","name":"Onboarding","description":"Issues related to onboarding new developers"},"Pages":{"color":"d7fd80","name":"Pages","description":"Issues related to configuring pages"},"skip-changelog":{"color":"06086F","name":"skip-changelog","description":"Adding this label to a PR prevents it from being listed in the changelog"},"Low":{"color":"79e53b","name":"Low","description":"An issue that is neither critical nor breaks a user flow"},"potential-duplicate":{"color":"d3cb2e","name":"potential-duplicate","description":"This label marks issues that are potential duplicates of already open issues"},"Audio Widget":{"color":"447B9A","name":"Audio Widget","description":"Issues related to Audio Widget"},"Firestore":{"color":"F1C2DF","name":"Firestore","description":"Issues related to the firestore Integration"},"New Widget":{"color":"be4cf2","name":"New Widget","description":"A request for a new widget"},"Performance":{"color":"d30e53","name":"Performance","description":"Page Load and evaluations"},"Modal Widget":{"color":"03846f","name":"Modal Widget","description":""},"UX Improvement":{"color":"f4a089","name":"UX Improvement","description":""},"S3":{"color":"c57928","name":"S3","description":"Issues related to the S3 plugin"},"Release Blocker":{"color":"5756bf","name":"Release Blocker","description":"This issue must be resolved before the release"},"safari":{"color":"51C6AA","name":"safari","description":"Bugs seen on safari browser"},"Example Apps":{"color":"1799b0","name":"Example Apps","description":"Example apps created for new signups"},"MultiSelect Widget":{"color":"AB62D4","name":"MultiSelect Widget","description":"Issues related to MultiSelect Widget"},"JS Editor":{"color":"48b992","name":"JS Editor","description":"Issues related to JS Editor"},"Widget Styling":{"color":"37EA75","name":"Widget Styling","description":"all about widget styling"},"Calendar Widget":{"color":"8c6644","name":"Calendar Widget","description":""},"JS":{"color":"e46785","name":"JS","description":"Issues related to JS on the platform"},"Website":{"color":"151720","name":"Website","description":"Related to www.appsmith.com website"},"Low effort":{"color":"8B59F0","name":"Low effort","description":"Something that'll take a few days to build"},"App Viewers Pod":{"color":"cd8ef9","name":"App Viewers Pod","description":"This label assigns issues to the app viewers pod"},"Checkbox Widget":{"color":"074ac6","name":"Checkbox Widget","description":""},"Spam":{"color":"620faf","name":"Spam","description":""},"Voice Recorder Widget":{"color":"85bc87","name":"Voice Recorder Widget","description":""},"Select Widget":{"color":"0c669e","name":"Select Widget","description":"Select or dropdown widget"},"Bug":{"color":"d73a4a","name":"Bug","description":"Something isn't working"},"Widget Validation":{"color":"6990BC","name":"Widget Validation","description":"Issues related to widget property validation"},"Generate Page":{"color":"f14274","name":"Generate Page","description":"Issures related to page generation"},"File Picker Widget":{"color":"6ae4f2","name":"File Picker Widget","description":""},"snowflake":{"color":"47075c","name":"snowflake","description":"Issues related to the snowflake Integration"},"Automation":{"color":"CCAF60","name":"Automation","description":""},"hotfix":{"color":"BA3F1D","name":"hotfix","description":""},"Team Managers Pod":{"color":"bddb81","name":"Team Managers Pod","description":"Issues that team managers care about for the security and efficiency of their teams"},"API pane":{"color":"e417c7","name":"API pane","description":"API configuration section"},"Import-Export-App":{"color":"a7768a","name":"Import-Export-App","description":"Issues related to importing and exporting apps"},"High effort":{"color":"A7E87B","name":"High effort","description":"Something that'll take more than a month to build"},"ACL":{"color":"747224","name":"ACL","description":"User permissions and access controls"},"Telemetry":{"color":"bc70f9","name":"Telemetry","description":"Issues related to instrumenting appsmith"},"Radio Widget":{"color":"91ef15","name":"Radio Widget","description":""},"Omnibar":{"color":"10b5ce","name":"Omnibar","description":"Issues related to the omnibar for navigation"},"Button Widget":{"color":"34efae","name":"Button Widget","description":""},"Switch widget":{"color":"33A8CE","name":"Switch widget","description":"The switch widget"},"Map Widget":{"color":"7eef7a","name":"Map Widget","description":""},"UI Building Pod":{"color":"e2ffb2","name":"UI Building Pod","description":""},"Task":{"color":"085630","name":"Task","description":"A simple Todo"},"Design System":{"color":"12b715","name":"Design System","description":"Design system"},"opera":{"color":"C63F5B","name":"opera","description":"Any issues identified on the opera browser"},"Login / Signup":{"color":"949fe0","name":"Login / Signup","description":"Authentication flows"},"Image Widget":{"color":"8de8ad","name":"Image Widget","description":""},"firefox":{"color":"6d56e2","name":"firefox","description":""},"Property Pane":{"color":"b356ff","name":"Property Pane","description":"Issues related to the behaviour of the property pane"},"Deployment":{"color":"bdf989","name":"Deployment","description":"Installation process of appsmith"},"Critical":{"color":"9b1b28","name":"Critical","description":"This issue needs immediate attention. Drop everything else"},"IDE":{"color":"61b2ee","name":"IDE","description":"Issues related to the IDE"},"Production":{"color":"b60205","name":"Production","description":""},"Dependencies":{"color":"0366d6","name":"Dependencies","description":"Pull requests that update a dependency file"},"Actions Pod":{"color":"61ed84","name":"Actions Pod","description":"Issues picked up by the action pod"},"Google Sheets":{"color":"51D86A","name":"Google Sheets","description":"Issues related to Google Sheets"},"Icon Button Widget":{"color":"D319CE","name":"Icon Button Widget","description":"Issues related to the icon button widget"},"Mongo":{"color":"fef2c0","name":"Mongo","description":"Issues related to Mongo DB plugin"},"Documentation":{"color":"a8dff7","name":"Documentation","description":"Improvements or additions to documentation"},"TestGap":{"color":"f28253","name":"TestGap","description":"Issues identified for test plan improvement"},"keyboard shortcut":{"color":"0688B6","name":"keyboard shortcut","description":""},"Git Version Control":{"color":"C4568E","name":"Git Version Control","description":"Issues related to version control"},"Reopen":{"color":"897548","name":"Reopen","description":""},"Redshift":{"color":"ABAEB5","name":"Redshift","description":"Issues related to the redshift integration"},"Date Picker Widget":{"color":"ef1ce1","name":"Date Picker Widget","description":""},"Entity Explorer":{"color":"a2e2f9","name":"Entity Explorer","description":"Issues related to navigation using the entity explorer"},"JS Linting & Errors":{"color":"E56AA5","name":"JS Linting & Errors","description":"Issues related to JS Linting and errors"},"iFrame":{"color":"3CD1DB","name":"iFrame","description":"Issues related to iFrame"},"Stale":{"color":"ededed","name":"Stale","description":null},"Debugger":{"color":"e79062","name":"Debugger","description":"Issues related to the debugger"},"Quick effort":{"color":"95ED65","name":"Quick effort","description":"Something that'll take a few hours to build"},"Text Widget":{"color":"d130d1","name":"Text Widget","description":""},"Video Widget":{"color":"23dd4b","name":"Video Widget","description":""},"Datasources":{"color":"f285e1","name":"Datasources","description":"Issues related to configuring datasource on appsmith"},"error":{"color":"B66773","name":"error","description":"All issues connected to error messages"},"Form Widget":{"color":"09ed77","name":"Form Widget","description":""},"Needs Triaging":{"color":"e8b851","name":"Needs Triaging","description":"Needs attention from maintainers to triage"},"Query Editor":{"color":"8887af","name":"Query Editor","description":"The section where a user can write DB queries."},"Autocomplete":{"color":"235708","name":"Autocomplete","description":"Issues related to the autocomplete"},"hacktoberfest":{"color":"0052cc","name":"hacktoberfest","description":"All issues that can be solved by the community during Hacktoberfest"},"Medium effort":{"color":"D31156","name":"Medium effort","description":"Something that'll take more than a week but less than a month to build"},"Release":{"color":"57e5e0","name":"Release","description":""},"High":{"color":"c94d14","name":"High","description":"This issue blocks a user from building or impacts a lot of users"},"Platform Pod":{"color":"500B69","name":"Platform Pod","description":"All issues related to using the appsmith platform"},"UI Performance":{"color":"1799b0","name":"UI Performance","description":"Issues related to UI performance"},"UI Builders Pod":{"color":"517fba","name":"UI Builders Pod","description":"Issues that UI Builders face using appsmith"},"Deploy Preview":{"color":"bfdadc","name":"Deploy Preview","description":"Issues found in Deploy Preview"},"Needs Tests":{"color":"8ee263","name":"Needs Tests","description":"Needs automated tests to assert a feature/bug fix"},"Refactor":{"color":"B96662","name":"Refactor","description":"needs refactoring of code"},"Divider Widget":{"color":"235708","name":"Divider Widget","description":"Issues related to the divider widget"},"Table Widget":{"color":"2eead1","name":"Table Widget","description":""},"Needs More Info":{"color":"e54c10","name":"Needs More Info","description":"Needs additional information"},"Good First Issue":{"color":"7057ff","name":"Good First Issue","description":"Good for newcomers"},"UI Improvement":{"color":"9aeef4","name":"UI Improvement","description":""},"Backend":{"color":"d4c5f9","name":"Backend","description":"This marks the issue or pull request to reference server code"},"Frontend":{"color":"87c7f2","name":"Frontend","description":"This label marks the issue or pull request to reference client code"},"In App Comms":{"color":"9168f4","name":"In App Comms","description":"Issues around communication with appsmith instances"},"Chart Widget":{"color":"616ecc","name":"Chart Widget","description":""},"regression":{"color":"ffe5bc","name":"regression","description":""},"List Widget":{"color":"8508A0","name":"List Widget","description":"Issues related to the list widget"},"Duplicate":{"color":"cfd3d7","name":"Duplicate","description":"This issue or pull request already exists"},"High impact":{"color":"853A9F","name":"High impact","description":""},"JS Snippets":{"color":"8d62d2","name":"JS Snippets","description":"issues related to JS Snippets"},"Copy Paste":{"name":"Copy Paste","description":"Issues related to copy paste","color":"b4f0a9"},"Drag & Drop":{"name":"Drag & Drop","description":"Issues related to the drag & drop experience","color":"92115a"},"SQL":{"name":"SQL","description":"Issues related to SQL Datasources","color":"a1633e"},"BE Coders Pod":{"color":"5d9848","name":"BE Coders Pod","description":"Issues related to users writing code to fetch and update data"},"FE Coders Pod":{"color":"a7effc","name":"FE Coders Pod","description":"Issues related to users writing javascript in appsmith"},"New Developers Pod":{"color":"6310da","name":"New Developers Pod","description":"Issues that new developers face while exploring the IDE"},"Sniping Mode":{"name":"Sniping Mode","description":"Issues related to sniping mode","color":"6310da"},"Redis":{"name":"Redis","description":"Issues related to Redis","color":"8b19cc"},"New Datasource":{"color":"9c0cf7","name":"New Datasource","description":"Requests for new datasources"},"Query Execution":{"color":"9c0cf7","name":"Query Execution","description":"Issues related to API / Query execution"},"Evaluated Value":{"name":"Evaluated Value","description":"Issues related to evaluated values","color":"39f6e7"},"Undo/Redo":{"name":"Undo/Redo","description":"Issues related to undo/redo","color":"f25880"},"App Navigation":{"name":"App Navigation","description":"Issues related to the topbar navigation and configuring it","color":"12b715"},"Responsive Viewport":{"color":"12b715","name":"Responsive Viewport","description":"Issues seen on different viewports like mobile"},"Canvas Zoom":{"name":"Canvas Zoom","description":"Issues related to zooming the canvas","color":"57da0d"},"Widgets Pane":{"name":"Widgets Pane","description":"Issues related to the discovery and organisation of widgets","color":"ad5d78"},"Invite users":{"color":"1799b0","name":"Invite users","description":"Invite users flow and any associated actions"},"View Mode":{"color":"1799b0","name":"View Mode","description":"Issues related to the view mode"},"User Education Pod":{"name":"User Education Pod","description":"Issues related to user education","color":"1799b0"},"Content":{"name":"Content","description":"For content related topics i.e blogs, templates, videos","color":"a8dff7"},"Embedding Apps":{"name":"Embedding Apps","description":"Issues related to embedding","color":"849aff"},"Slash Command":{"name":"Slash Command","description":"Issues related to the slash command","color":"a0608e"},"Widget Property":{"name":"Widget Property","description":"Issues related to adding / modifying widget properties across widgets","color":"5e92cb"},"Windows":{"name":"Windows","description":"Issues related exclusively to Windows systems","color":"b4cb8a"},"Old App Issues":{"name":"Old App Issues","description":"Issues related to apps old apps a few weeks old and app issues in stale browser session","color":"87ab18"},"Document Viewer Widget":{"name":"Document Viewer Widget","description":"Issues related to Document Viewer Widget","color":"899d4b"},"Radio Group Widget":{"name":"Radio Group Widget","description":"Issues related to radio group widget","color":"b68495"},"Super Admin":{"name":"Super Admin","description":"Issues related to the super admin page","color":"b68495"},"Postgres":{"name":"Postgres","description":"Postgres related issues","color":"b68495"},"REST API plugin":{"name":"REST API plugin","description":"REST API plugin related issues","color":"9f538c"},"New JS Function":{"name":"New JS Function","description":"Issues related to adding a JS Function","color":"8e8aa4"},"Cannot Reproduce Issue":{"color":"93c9cc","name":"Cannot Reproduce Issue","description":"Issues that cannot be reproduced"},"Widget Grouping":{"name":"Widget Grouping","description":"Issues related to Widget Grouping","color":"a49951"},"K8s":{"name":"K8s","description":"Kubernetes related issues","color":"235b3b"},"Docker":{"name":"Docker","description":"Issues related to docker","color":"623a07"},"Camera Widget":{"name":"Camera Widget","description":"Issues and enhancements related to camera widget","color":"c7ace5"},"SAAS Plugins":{"name":"SAAS Plugins","description":"Issues related to SAAS Plugins","color":"ef9c9d"},"UQI components":{"name":"UQI components","description":"UQI specifically for components like sorting pagination and projection","color":"d7771f"},"UQI validations":{"name":"UQI validations","description":"validations for UQI datasources and action forms","color":"d7771f"},"Action form":{"name":"Action form","description":"Action forms for queries and API operations","color":"d7771f"},"UQI migration":{"name":"UQI migration","description":"migration of various datasources to uqi","color":"d7771f"},"JS Promises":{"name":"JS Promises","description":"Issues related to promises","color":"d7771f"},"OnPageLoad":{"name":"OnPageLoad","description":"OnPageLoad settings for JS functions","color":"63744e"},"Function execution":{"name":"Function execution","description":"JS function execution","color":"a302b0"},"JS Refactoring":{"name":"JS Refactoring","description":"cascading refactors to user JS due to user changes","color":"a302b0"},"JS Usability":{"name":"JS Usability","description":"usability issues with JS editor and JS elsewhere","color":"a302b0"},"Currency Input Widget":{"name":"Currency Input Widget","description":"Issues related to currency input widget","color":"b2164f"},"TreeSelect":{"name":"TreeSelect","description":"Issues related to TreeSelect Widget","color":"a1633e"},"MultiTree Select Widget":{"name":"MultiTree Select Widget","description":"Issues related to MultiTree Select Widget","color":"a1633e"},"Welcome Screen":{"name":"Welcome Screen","description":"Issues related to the welcome screen","color":"3897be"},"Query Templates":{"name":"Query Templates","description":"Issues related to query templates","color":"8f02d6"},"Realtime Commenting":{"color":"a70b86","name":"Realtime Commenting","description":"In-app communication between teams"},"Phone Input Widget":{"name":"Phone Input Widget","description":"Issues related to the Phone Input widget","color":"a70b86"},"JSON Form":{"name":"JSON Form","description":"Issue / features related to the JSON form wiget","color":"46b209"},"All Widgets":{"name":"All Widgets","description":"Issues related to all widgets","color":"972b36"},"V1":{"name":"V1","description":"V1","color":"67ab2e"},"Plugin Development":{"name":"Plugin Development","description":"Issues related to plugin development","color":"5e9d7b"},"Reflow & Resize":{"name":"Reflow & Resize","description":"All issues related to reflow and resize experience","color":"748a13"},"App Theming":{"name":"App Theming","description":"Items that are related to the App level theming controls epic","color":"8bf430"},"SSO":{"name":"SSO","description":"Issues, requests and enhancements around Single sign-on.","color":"bf019b"},"Multi User Realtime":{"name":"Multi User Realtime","description":"Issues related to multiple users using or editing an application","color":"e7b6ce"},"Templates":{"name":"Templates","description":"Issues related to Templates","color":"c3b541"},"Ready for design":{"name":"Ready for design","description":"this issue is ready for design: it contains clear problem statements and other required information","color":"ebf442"},"Support":{"name":"Support","description":"Issues created by the A-force team to address user queries","color":"1740f3"},"Button Group widget":{"name":"Button Group widget","description":"Issue and enhancements related to the button group widget","color":"f17025"}}} \ No newline at end of file diff --git a/.github/workflows/TestReuseActions.yml b/.github/workflows/TestReuseActions.yml index 7d469365f3..82744711db 100644 --- a/.github/workflows/TestReuseActions.yml +++ b/.github/workflows/TestReuseActions.yml @@ -103,7 +103,7 @@ jobs: # Install all the dependencies - name: Install dependencies if: steps.run_result.outputs.run_result != 'success' - run: yarn install + run: yarn install --frozen-lockfile - name: Set the build environment based on the branch if: steps.run_result.outputs.run_result != 'success' @@ -609,7 +609,7 @@ jobs: # Install all the dependencies - name: Install dependencies if: steps.run_result.outputs.run_result != 'success' - run: yarn install + run: yarn install --frozen-lockfile - name: Download the react build artifact if: steps.run_result.outputs.run_result != 'success' diff --git a/.github/workflows/client-build.yml b/.github/workflows/client-build.yml index 396b2be215..3941241633 100644 --- a/.github/workflows/client-build.yml +++ b/.github/workflows/client-build.yml @@ -77,7 +77,7 @@ jobs: # Install all the dependencies - name: Install dependencies - run: yarn install + run: yarn install --frozen-lockfile - name: Set the build environment based on the branch id: vars diff --git a/.github/workflows/copy-labels.yml b/.github/workflows/copy-labels.yml new file mode 100644 index 0000000000..a45de218c0 --- /dev/null +++ b/.github/workflows/copy-labels.yml @@ -0,0 +1,11 @@ +name: Copy labels from a connected issue to the PR + +on: + pull_request: + types: [opened, labeled, unlabeled, assigned, edited, reopened, synchronize, ready_for_review] +jobs: + copy-labels-from-issue: + runs-on: ubuntu-latest + steps: + - name: Check and copy labels + uses: hetunandu/copy-labels-from-issue@v1 diff --git a/.github/workflows/github-release.yml b/.github/workflows/github-release.yml index 01775a2eba..6e66433520 100644 --- a/.github/workflows/github-release.yml +++ b/.github/workflows/github-release.yml @@ -76,7 +76,7 @@ jobs: ${{ runner.OS }}- - name: Install dependencies - run: yarn install + run: yarn install --frozen-lockfile - name: Create the bundle env: diff --git a/.github/workflows/integration-tests-command.yml b/.github/workflows/integration-tests-command.yml index 1a0d7fb36f..f5e1d3cae2 100644 --- a/.github/workflows/integration-tests-command.yml +++ b/.github/workflows/integration-tests-command.yml @@ -214,7 +214,7 @@ jobs: # Install all the dependencies - name: Install dependencies if: steps.run_result.outputs.run_result != 'success' - run: yarn install + run: yarn install --frozen-lockfile - name: Set the build environment based on the branch if: steps.run_result.outputs.run_result != 'success' @@ -331,6 +331,434 @@ jobs: # Set status = success - run: echo "::set-output name=run_result::success" > ~/run_result + buildRts: + defaults: + run: + working-directory: app/rts + runs-on: ubuntu-latest + # Only run this workflow for internally triggered events + if: github.event_name == 'repository_dispatch' && + github.event.client_payload.slash_command.sha != '' && + contains(github.event.client_payload.pull_request.head.sha, github.event.client_payload.slash_command.sha) + + steps: + # Checkout the code + - uses: actions/checkout@v2 + with: + fetch-depth: 0 + + # Timestamp will be used to create cache key + - id: timestamp + run: echo "::set-output name=timestamp::$(timestamp +'%Y-%m-%dT%H:%M:%S')" + + # In case this is second attempt try restoring status of the prior attempt from cache + - name: Restore the previous run result + uses: actions/cache@v2 + with: + path: | + ~/run_result + key: ${{ github.run_id }}-${{ github.job }}-${{ steps.timestamp.outputs.timestamp }} + restore-keys: | + ${{ github.run_id }}-${{ github.job }}- + + # Fetch prior run result + - name: Get the previous run result + id: run_result + run: cat ~/run_result 2>/dev/null || echo 'default' + + # Incase of prior failure run the job + - if: steps.run_result.outputs.run_result != 'success' + run: echo "I'm alive!" && exit 0 + + - name: Use Node.js 14.15.4 + if: steps.run_result.outputs.run_result != 'success' + uses: actions/setup-node@v1 + with: + node-version: "14.15.4" + + # Here, the GITHUB_REF is of type /refs/head/. We extract branch_name from this by removing the + # first 11 characters. This can be used to build images for several branches + # Since this is an unreleased build, we get the latest released version number, increment the minor number in it, + # append a `-SNAPSHOT` at it's end to prepare the snapshot version number. This is used as the project's version. + - name: Get the version to tag the Docker image + if: steps.run_result.outputs.run_result != 'success' + id: vars + run: | + # Since this is an unreleased build, we set the version to incremented version number with a + # `-SNAPSHOT` suffix. + latest_released_version="$(git tag --list 'v*' --sort=-version:refname | head -1)" + echo "latest_released_version = $latest_released_version" + next_version="$(echo "$latest_released_version" | awk -F. -v OFS=. '{ $NF++; print }')" + echo "next_version = $next_version" + echo ::set-output name=version::$next_version-SNAPSHOT + echo ::set-output name=tag::$(echo ${GITHUB_REF:11}) + + - name: Build + if: steps.run_result.outputs.run_result != 'success' + run: | + echo 'export const VERSION = "${{ steps.vars.outputs.version }}"' > src/version.js + ./build.sh + ls -l dist + + # Restore the previous built bundle if present. If not push the newly built into the cache + - name: Restore the previous bundle + uses: actions/cache@v2 + with: + path: | + app/rts/dist/ + key: ${{ github.run_id }}-${{ github.job }}-${{ steps.timestamp.outputs.timestamp }} + restore-keys: | + ${{ github.run_id }}-${{ github.job }} + + # Restore the previous built bundle if present. If not push the newly built into the cache + - name: Restore the previous bundle + uses: actions/cache@v2 + with: + path: | + app/rts/node_modules/ + key: ${{ github.run_id }}-${{ github.job }}-${{ steps.timestamp.outputs.timestamp }} + restore-keys: | + ${{ github.run_id }}-${{ github.job }} + + # Upload the build artifact so that it can be used by the test & deploy job in the workflow + - name: Upload server build bundle + uses: actions/upload-artifact@v2 + with: + name: rts-build + path: app/rts/dist/ + + - name: Upload RTS dependencies bundle + uses: actions/upload-artifact@v2 + with: + name: rts-build-deps + path: app/rts/node_modules/ + + fat-conatiner-test: + needs: [build, server-build, buildRts] + # Only run if the build step is successful + if: success() + runs-on: ubuntu-latest + defaults: + run: + shell: bash + strategy: + fail-fast: false + + # Service containers to run with this job. Required for running tests + services: + # Label used to access the service container + redis: + # Docker Hub image for Redis + image: redis + ports: + # Opens tcp port 6379 on the host and service container + - 6379:6379 + mongo: + image: mongo + ports: + - 27017:27017 + + steps: + # Check out merge commit + - name: Fork based /ok-to-test checkout + uses: actions/checkout@v2 + with: + ref: "refs/pull/${{ github.event.client_payload.pull_request.number }}/merge" + + # Timestamp will be used to create cache key + - id: timestamp + run: echo "::set-output name=timestamp::$(timestamp +'%Y-%m-%dT%H:%M:%S')" + + # In case this is second attempt try restoring status of the prior attempt from cache + - name: Restore the previous run result + uses: martijnhols/actions-cache@v3 + with: + path: | + ~/run_result + key: ${{ github.run_id }}-${{ github.job }}-${{ steps.timestamp.outputs.timestamp }}-${{ matrix.job }} + restore-keys: | + ${{ github.run_id }}-${{ github.job }}-${{ matrix.job }} + + # Fetch prior run result + - name: Get the previous run result + id: run_result + run: cat ~/run_result 2>/dev/null || echo 'default' + + # In case this is second attempt try restoring failed tests + - name: Restore the previous failed combine result + if: steps.run_result.outputs.run_result == 'failedtest' + uses: martijnhols/actions-cache/restore@v3 + with: + path: | + ~/combined_failed_spec + key: ${{ github.run_id }}-"ui-test-result"-${{ steps.timestamp.outputs.timestamp }} + restore-keys: | + ${{ github.run_id }}-${{ github.job }} + + # failed_spec_env will contain list of all failed specs + # We are using evnironment variable instead of regular to support multiline + - name: Get failed_spec + if: steps.run_result.outputs.run_result == 'failedtest' + run: | + failed_spec_env=$(cat ~/combined_failed_spec) + echo "failed_spec_env<> $GITHUB_ENV + echo "$failed_spec_env" >> $GITHUB_ENV + echo "EOF" >> $GITHUB_ENV + + - if: steps.run_result.outputs.run_result != 'success' && steps.run_result.outputs.run_result != 'failedtest' + run: echo "Starting full run" && exit 0 + + - if: steps.run_result.outputs.run_result == 'failedtest' + run: echo "Rerunning failed tests" && exit 0 + + - name: cat run_result + run: echo ${{ steps.run_result.outputs.run_result }} + + # Setup Java + - name: Set up JDK 1.11 + if: steps.run_result.outputs.run_result != 'success' + uses: actions/setup-java@v1 + with: + java-version: "11.0.10" + + - name: Download the react build artifact + uses: actions/download-artifact@v2 + with: + name: build + path: app/client/build + + - name: Download the server build artifact + uses: actions/download-artifact@v2 + with: + name: build + path: app/server/dist/ + + - name: Download the rts build artifact + uses: actions/download-artifact@v2 + with: + name: rts-build + path: app/rts/dist/ + + - name: Download the rts build artifact + uses: actions/download-artifact@v2 + with: + name: rts-build-deps + path: app/rts/node_modules/ + + - name: Build docker image + if: steps.run_result.outputs.run_result != 'success' + working-directory: "." + run: | + docker build -t fatcontainer . + + - name: Load docker image + if: steps.run_result.outputs.run_result != 'success' + env: + APPSMITH_LICENSE_KEY: ${{ secrets.APPSMITH_LICENSE_KEY }} + working-directory: "." + run: | + mkdir -p fatcontainerlocal/stacks/configuration/ + cd fatcontainerlocal + docker run -d --name appsmith -p 80:80 -p 9001:9001 \ + -v "$PWD/stacks:/appsmith-stacks" fatcontainer + sudo chmod a+rw stacks/configuration/docker.env + sudo echo "APPSMITH_LICENSE_KEY=$APPSMITH_LICENSE_KEY" >> stacks/configuration/docker.env + +# - name: Restart Appsmith +# if: steps.run_result.outputs.run_result != 'success' +# run: | +# docker restart appsmith + + - name: Use Node.js 14.15.4 + if: steps.run_result.outputs.run_result != 'success' + uses: actions/setup-node@v1 + with: + node-version: "14.15.4" + + # Install all the dependencies + - name: Install dependencies + if: steps.run_result.outputs.run_result != 'success' + run: | + cd app/client + yarn install + + - name: Setting up the cypress tests + if: steps.run_result.outputs.run_result != 'success' + shell: bash + env: + APPSMITH_SSL_CERTIFICATE: ${{ secrets.APPSMITH_SSL_CERTIFICATE }} + APPSMITH_SSL_KEY: ${{ secrets.APPSMITH_SSL_KEY }} + CYPRESS_URL: ${{ secrets.CYPRESS_URL }} + CYPRESS_USERNAME: ${{ secrets.CYPRESS_USERNAME }} + CYPRESS_PASSWORD: ${{ secrets.CYPRESS_PASSWORD }} + CYPRESS_TESTUSERNAME1: ${{ secrets.CYPRESS_TESTUSERNAME1 }} + CYPRESS_TESTPASSWORD1: ${{ secrets.CYPRESS_TESTPASSWORD1 }} + CYPRESS_TESTUSERNAME2: ${{ secrets.CYPRESS_TESTUSERNAME2 }} + CYPRESS_TESTPASSWORD2: ${{ secrets.CYPRESS_TESTPASSWORD1 }} + CYPRESS_S3_ACCESS_KEY: ${{ secrets.CYPRESS_S3_ACCESS_KEY }} + CYPRESS_S3_SECRET_KEY: ${{ secrets.CYPRESS_S3_SECRET_KEY }} + CYPRESS_GITHUB_PERSONAL_ACCESS_TOKEN: ${{ secrets.CYPRESS_GITHUB_PERSONAL_ACCESS_TOKEN }} + CYPRESS_TEST_GITHUB_USER_NAME: ${{ secrets.CYPRESS_TEST_GITHUB_USER_NAME }} + APPSMITH_DISABLE_TELEMETRY: true + APPSMITH_GOOGLE_MAPS_API_KEY: ${{ secrets.APPSMITH_GOOGLE_MAPS_API_KEY }} + POSTGRES_PASSWORD: postgres + run: | + cd app/client + chmod a+x ./cypress/setup-test-fat.sh + ./cypress/setup-test-fat.sh + + - name: Run the cypress test + if: steps.run_result.outputs.run_result != 'success' && steps.run_result.outputs.run_result != 'failedtest' + uses: cypress-io/github-action@v2 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }} + CYPRESS_PROJECT_ID: ${{ secrets.CYPRESS_PROJECT_ID }} + CYPRESS_USERNAME: ${{ secrets.CYPRESS_USERNAME }} + CYPRESS_PASSWORD: ${{ secrets.CYPRESS_PASSWORD }} + CYPRESS_TESTUSERNAME1: ${{ secrets.CYPRESS_TESTUSERNAME1 }} + CYPRESS_TESTPASSWORD1: ${{ secrets.CYPRESS_TESTPASSWORD1 }} + CYPRESS_TESTUSERNAME2: ${{ secrets.CYPRESS_TESTUSERNAME2 }} + CYPRESS_TESTPASSWORD2: ${{ secrets.CYPRESS_TESTPASSWORD1 }} + CYPRESS_S3_ACCESS_KEY: ${{ secrets.CYPRESS_S3_ACCESS_KEY }} + CYPRESS_S3_SECRET_KEY: ${{ secrets.CYPRESS_S3_SECRET_KEY }} + CYPRESS_GITHUB_PERSONAL_ACCESS_TOKEN: ${{ secrets.CYPRESS_GITHUB_PERSONAL_ACCESS_TOKEN }} + CYPRESS_TEST_GITHUB_USER_NAME: ${{ secrets.CYPRESS_TEST_GITHUB_USER_NAME }} + APPSMITH_DISABLE_TELEMETRY: true + APPSMITH_GOOGLE_MAPS_API_KEY: ${{ secrets.APPSMITH_GOOGLE_MAPS_API_KEY }} + COMMIT_INFO_MESSAGE: ${{ github.event.pull_request.title }} + with: + browser: chrome + headless: true + record: true + install: false + parallel: true + config-file: cypress_fat.json + group: "Electrons on Github Action Fat Container" + spec: "cypress/integration/Smoke_TestSuite_Fat/**/*" + working-directory: app/client + # tag will be either "push" or "pull_request" + tag: ${{ github.event_name }} + env: "NODE_ENV=development" + + # Incase of second attemtp only run failed specs + - name: Run the cypress test with failed tests + if: steps.run_result.outputs.run_result == 'failedtest' + uses: cypress-io/github-action@v2 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }} + CYPRESS_PROJECT_ID: ${{ secrets.CYPRESS_PROJECT_ID }} + CYPRESS_USERNAME: ${{ secrets.CYPRESS_USERNAME }} + CYPRESS_PASSWORD: ${{ secrets.CYPRESS_PASSWORD }} + CYPRESS_TESTUSERNAME1: ${{ secrets.CYPRESS_TESTUSERNAME1 }} + CYPRESS_TESTPASSWORD1: ${{ secrets.CYPRESS_TESTPASSWORD1 }} + CYPRESS_TESTUSERNAME2: ${{ secrets.CYPRESS_TESTUSERNAME2 }} + CYPRESS_TESTPASSWORD2: ${{ secrets.CYPRESS_TESTPASSWORD1 }} + CYPRESS_S3_ACCESS_KEY: ${{ secrets.CYPRESS_S3_ACCESS_KEY }} + CYPRESS_S3_SECRET_KEY: ${{ secrets.CYPRESS_S3_SECRET_KEY }} + CYPRESS_GITHUB_PERSONAL_ACCESS_TOKEN: ${{ secrets.CYPRESS_GITHUB_PERSONAL_ACCESS_TOKEN }} + CYPRESS_TEST_GITHUB_USER_NAME: ${{ secrets.CYPRESS_TEST_GITHUB_USER_NAME }} + APPSMITH_DISABLE_TELEMETRY: true + APPSMITH_GOOGLE_MAPS_API_KEY: ${{ secrets.APPSMITH_GOOGLE_MAPS_API_KEY }} + COMMIT_INFO_MESSAGE: ${{ github.event.pull_request.title }} + with: + browser: chrome + headless: true + record: true + install: false + parallel: true + config-file: cypress_fat.json + group: "Electrons on Github Action" + spec: ${{ env.failed_spec_env }} + working-directory: app/client + # tag will be either "push" or "pull_request" + tag: ${{ github.event_name }} + env: "NODE_ENV=development" + + # Set status = failedtest + - name: Set fail if there are test failures + if: failure() + run: echo "::set-output name=run_result::failedtest" > ~/run_result + + # Create a directory ~/failed_spec and add a dummy file + # This will ensure upload and download steps are successfull + - name: Create direcotrs for failed tests + if: always() + run: | + mkdir -p ~/failed_spec + echo "empty" >> ~/failed_spec/dummy-${{ matrix.job }} + + # add list failed tests to a file + - name: Incase of test failures copy them to a file + if: failure() + run: | + cd ${{ github.workspace }}/app/client/cypress/ + find screenshots -type d|grep -i spec |sed 's/screenshots/cypress\/integration/g' > ~/failed_spec/failed_spec-${{ matrix.job }} + + # Upload failed test list using common path for all matrix job + - name: Upload failed test list artifact + if: always() + uses: actions/upload-artifact@v2 + with: + name: failed-spec + path: ~/failed_spec + + # Force store previous run result to cache + - name: Store the previous run result + if: failure() + uses: martijnhols/actions-cache/save@v3 + with: + path: | + ~/run_result + key: ${{ github.run_id }}-${{ github.job }}-${{ steps.timestamp.outputs.timestamp }}-${{ matrix.job }} + restore-keys: | + ${{ github.run_id }}-${{ github.job }}-${{ matrix.job }} + + # Force store previous failed test list to cache + - name: Store the previous failed test result + if: failure() + uses: martijnhols/actions-cache/save@v3 + with: + path: | + ~/failed_spec + key: ${{ github.run_id }}-${{ github.job }}-${{ steps.timestamp.outputs.timestamp }}-${{ matrix.job }} + restore-keys: | + ${{ github.run_id }}-${{ github.job }}-${{ matrix.job }} + + # Upload the screenshots as artifacts if there's a failure + - uses: actions/upload-artifact@v1 + if: failure() + with: + name: cypress-screenshots-${{ matrix.job }} + path: app/client/cypress/screenshots/ + + - name: Restore the previous bundle + uses: actions/cache@v2 + with: + path: | + app/client/cypress/snapshots/ + key: ${{ github.run_id }}-${{ github.job }}-${{ steps.timestamp.outputs.timestamp }}-${{ matrix.job }} + restore-keys: | + ${{ github.run_id }}-${{ github.job }}-${{ matrix.job }} + + # Upload the snapshots as artifacts for layout validation + - uses: actions/upload-artifact@v1 + with: + name: cypress-snapshots-visualRegression + path: app/client/cypress/snapshots/ + + # Upload the log artifact so that it can be used by the test & deploy job in the workflow + - name: Upload server logs bundle on failure + uses: actions/upload-artifact@v2 + if: failure() + with: + name: server-logs-${{ matrix.job }} + path: app/server/server-logs.log + + # Set status = success + - run: echo "::set-output name=run_result::success" > ~/run_result + ui-test: needs: [build, server-build] # Only run if the build step is successful @@ -344,7 +772,7 @@ jobs: fail-fast: false matrix: job: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23] - + # Service containers to run with this job. Required for running tests services: # Label used to access the service container @@ -443,7 +871,7 @@ jobs: # Install all the dependencies - name: Install dependencies if: steps.run_result.outputs.run_result != 'success' - run: yarn install + run: yarn install --frozen-lockfile - name: Download the react build artifact if: steps.run_result.outputs.run_result != 'success' @@ -935,7 +1363,7 @@ jobs: # Install all the dependencies - name: Install dependencies if: steps.run_result.outputs.run_result != 'success' - run: yarn install + run: yarn install --frozen-lockfile - name: Download the react build artifact if: steps.run_result.outputs.run_result != 'success' @@ -1018,7 +1446,7 @@ jobs: if: steps.run_result.outputs.run_result != 'success' working-directory: app/client/perf shell: bash - run: yarn install + run: yarn install --frozen-lockfile - name: Change test script permissions if: steps.run_result.outputs.run_result != 'success' diff --git a/.github/workflows/test-build-docker-image.yml b/.github/workflows/test-build-docker-image.yml index df3a1e136e..1f7d95ae3d 100644 --- a/.github/workflows/test-build-docker-image.yml +++ b/.github/workflows/test-build-docker-image.yml @@ -109,7 +109,7 @@ jobs: # Install all the dependencies - name: Install dependencies if: steps.run_result.outputs.run_result != 'success' - run: yarn install + run: yarn install --frozen-lockfile - name: Set the build environment based on the branch if: steps.run_result.outputs.run_result != 'success' @@ -404,6 +404,345 @@ jobs: name: rts-build-deps path: app/rts/node_modules/ + fat-container-test: + needs: [buildClient, buildServer, buildRts] + # Only run if the build step is successful + # If the build has been triggered manually via workflow_dispatch or via a push to protected branches + # then we don't check for the PR approved state + if: | + success() && + (github.event_name == 'workflow_dispatch' || + github.event_name == 'push' || + (github.event_name == 'pull_request_review' && + github.event.review.state == 'approved' && + github.event.pull_request.head.repo.full_name == github.repository)) + runs-on: ubuntu-latest + defaults: + run: + shell: bash + strategy: + fail-fast: false + + # Service containers to run with this job. Required for running tests + services: + # Label used to access the service container + redis: + # Docker Hub image for Redis + image: redis + ports: + # Opens tcp port 6379 on the host and service container + - 6379:6379 + mongo: + image: mongo + ports: + - 27017:27017 + + steps: + # Checkout the code + - name: Checkout the merged commit from PR and base branch + if: github.event_name == 'pull_request_review' + uses: actions/checkout@v2 + with: + ref: refs/pull/${{ github.event.pull_request.number }}/merge + + - name: Checkout the head commit of the branch + if: github.event_name == 'push' || github.event_name == 'workflow_dispatch' + uses: actions/checkout@v2 + + # Timestamp will be used to create cache key + - id: timestamp + run: echo "::set-output name=timestamp::$(timestamp +'%Y-%m-%dT%H:%M:%S')" + + # In case this is second attempt try restoring status of the prior attempt from cache + - name: Restore the previous run result + uses: martijnhols/actions-cache@v3 + with: + path: | + ~/run_result + key: ${{ github.run_id }}-${{ github.job }}-${{ steps.timestamp.outputs.timestamp }}-${{ matrix.job }} + restore-keys: | + ${{ github.run_id }}-${{ github.job }}-${{ matrix.job }} + + # Fetch prior run result + - name: Get the previous run result + id: run_result + run: cat ~/run_result 2>/dev/null || echo 'default' + + # In case this is second attempt try restoring failed tests + - name: Restore the previous failed combine result + if: steps.run_result.outputs.run_result == 'failedtest' + uses: martijnhols/actions-cache/restore@v3 + with: + path: | + ~/combined_failed_spec + key: ${{ github.run_id }}-"ui-test-result"-${{ steps.timestamp.outputs.timestamp }} + restore-keys: | + ${{ github.run_id }}-${{ github.job }} + + # failed_spec_env will contain list of all failed specs + # We are using evnironment variable instead of regular to support multiline + - name: Get failed_spec + if: steps.run_result.outputs.run_result == 'failedtest' + run: | + failed_spec_env=$(cat ~/combined_failed_spec) + echo "failed_spec_env<> $GITHUB_ENV + echo "$failed_spec_env" >> $GITHUB_ENV + echo "EOF" >> $GITHUB_ENV + + - if: steps.run_result.outputs.run_result != 'success' && steps.run_result.outputs.run_result != 'failedtest' + run: echo "Starting full run" && exit 0 + + - if: steps.run_result.outputs.run_result == 'failedtest' + run: echo "Rerunning failed tests" && exit 0 + + - name: cat run_result + run: echo ${{ steps.run_result.outputs.run_result }} + + # Setup Java + - name: Set up JDK 1.11 + if: steps.run_result.outputs.run_result != 'success' + uses: actions/setup-java@v1 + with: + java-version: "11.0.10" + + - name: Download the react build artifact + uses: actions/download-artifact@v2 + with: + name: client-build + path: app/client/build + + - name: Download the server build artifact + uses: actions/download-artifact@v2 + with: + name: server-build + path: app/server/dist + + - name: Download the rts build artifact + uses: actions/download-artifact@v2 + with: + name: rts-build + path: app/rts/dist + + - name: Download the rts build artifact + uses: actions/download-artifact@v2 + with: + name: rts-build-deps + path: app/rts/node_modules/ + + - name: Build docker image + if: success() && github.ref == 'refs/heads/release' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch') + working-directory: "." + run: | + docker build -t fatcontainer . + + - name: Load docker image + if: success() && github.ref == 'refs/heads/release' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch') + env: + APPSMITH_LICENSE_KEY: ${{ secrets.APPSMITH_LICENSE_KEY }} + working-directory: "." + run: | + mkdir -p fatcontainerlocal/stacks/configuration/ + cd fatcontainerlocal + docker run -d --name appsmith -p 80:80 -p 9001:9001 \ + -v "$PWD/stacks:/appsmith-stacks" fatcontainer + sudo chmod a+rw stacks/configuration/docker.env + sudo echo "APPSMITH_LICENSE_KEY=$APPSMITH_LICENSE_KEY" >> stacks/configuration/docker.env + +# - name: Restart Appsmith +# if: steps.run_result.outputs.run_result != 'success' +# run: | +# docker restart appsmith + + - name: Use Node.js 14.15.4 + if: steps.run_result.outputs.run_result != 'success' + uses: actions/setup-node@v1 + with: + node-version: "14.15.4" + + # Install all the dependencies + - name: Install dependencies + if: steps.run_result.outputs.run_result != 'success' + run: | + cd app/client + yarn install + + - name: Setting up the cypress tests + if: steps.run_result.outputs.run_result != 'success' + shell: bash + env: + APPSMITH_SSL_CERTIFICATE: ${{ secrets.APPSMITH_SSL_CERTIFICATE }} + APPSMITH_SSL_KEY: ${{ secrets.APPSMITH_SSL_KEY }} + CYPRESS_URL: ${{ secrets.CYPRESS_URL }} + CYPRESS_USERNAME: ${{ secrets.CYPRESS_USERNAME }} + CYPRESS_PASSWORD: ${{ secrets.CYPRESS_PASSWORD }} + CYPRESS_TESTUSERNAME1: ${{ secrets.CYPRESS_TESTUSERNAME1 }} + CYPRESS_TESTPASSWORD1: ${{ secrets.CYPRESS_TESTPASSWORD1 }} + CYPRESS_TESTUSERNAME2: ${{ secrets.CYPRESS_TESTUSERNAME2 }} + CYPRESS_TESTPASSWORD2: ${{ secrets.CYPRESS_TESTPASSWORD1 }} + CYPRESS_S3_ACCESS_KEY: ${{ secrets.CYPRESS_S3_ACCESS_KEY }} + CYPRESS_S3_SECRET_KEY: ${{ secrets.CYPRESS_S3_SECRET_KEY }} + CYPRESS_GITHUB_PERSONAL_ACCESS_TOKEN: ${{ secrets.CYPRESS_GITHUB_PERSONAL_ACCESS_TOKEN }} + CYPRESS_TEST_GITHUB_USER_NAME: ${{ secrets.CYPRESS_TEST_GITHUB_USER_NAME }} + APPSMITH_DISABLE_TELEMETRY: true + APPSMITH_GOOGLE_MAPS_API_KEY: ${{ secrets.APPSMITH_GOOGLE_MAPS_API_KEY }} + POSTGRES_PASSWORD: postgres + run: | + cd app/client + chmod a+x ./cypress/setup-test-fat.sh + ./cypress/setup-test-fat.sh + + - name: Run the cypress test + if: steps.run_result.outputs.run_result != 'success' && steps.run_result.outputs.run_result != 'failedtest' + uses: cypress-io/github-action@v2 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }} + CYPRESS_PROJECT_ID: ${{ secrets.CYPRESS_PROJECT_ID }} + CYPRESS_USERNAME: ${{ secrets.CYPRESS_USERNAME }} + CYPRESS_PASSWORD: ${{ secrets.CYPRESS_PASSWORD }} + CYPRESS_TESTUSERNAME1: ${{ secrets.CYPRESS_TESTUSERNAME1 }} + CYPRESS_TESTPASSWORD1: ${{ secrets.CYPRESS_TESTPASSWORD1 }} + CYPRESS_TESTUSERNAME2: ${{ secrets.CYPRESS_TESTUSERNAME2 }} + CYPRESS_TESTPASSWORD2: ${{ secrets.CYPRESS_TESTPASSWORD1 }} + CYPRESS_S3_ACCESS_KEY: ${{ secrets.CYPRESS_S3_ACCESS_KEY }} + CYPRESS_S3_SECRET_KEY: ${{ secrets.CYPRESS_S3_SECRET_KEY }} + CYPRESS_GITHUB_PERSONAL_ACCESS_TOKEN: ${{ secrets.CYPRESS_GITHUB_PERSONAL_ACCESS_TOKEN }} + CYPRESS_TEST_GITHUB_USER_NAME: ${{ secrets.CYPRESS_TEST_GITHUB_USER_NAME }} + APPSMITH_DISABLE_TELEMETRY: true + APPSMITH_GOOGLE_MAPS_API_KEY: ${{ secrets.APPSMITH_GOOGLE_MAPS_API_KEY }} + COMMIT_INFO_MESSAGE: ${{ github.event.pull_request.title }} + with: + browser: chrome + headless: true + record: true + install: false + parallel: true + config-file: cypress_fat.json + group: "Electrons on Github Action Fat Container" + spec: "cypress/integration/Smoke_TestSuite_Fat/**/*" + working-directory: app/client + # tag will be either "push" or "pull_request" + tag: ${{ github.event_name }} + env: "NODE_ENV=development" + + # Incase of second attemtp only run failed specs + - name: Run the cypress test with failed tests + if: steps.run_result.outputs.run_result == 'failedtest' + uses: cypress-io/github-action@v2 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }} + CYPRESS_PROJECT_ID: ${{ secrets.CYPRESS_PROJECT_ID }} + CYPRESS_USERNAME: ${{ secrets.CYPRESS_USERNAME }} + CYPRESS_PASSWORD: ${{ secrets.CYPRESS_PASSWORD }} + CYPRESS_TESTUSERNAME1: ${{ secrets.CYPRESS_TESTUSERNAME1 }} + CYPRESS_TESTPASSWORD1: ${{ secrets.CYPRESS_TESTPASSWORD1 }} + CYPRESS_TESTUSERNAME2: ${{ secrets.CYPRESS_TESTUSERNAME2 }} + CYPRESS_TESTPASSWORD2: ${{ secrets.CYPRESS_TESTPASSWORD1 }} + CYPRESS_S3_ACCESS_KEY: ${{ secrets.CYPRESS_S3_ACCESS_KEY }} + CYPRESS_S3_SECRET_KEY: ${{ secrets.CYPRESS_S3_SECRET_KEY }} + CYPRESS_GITHUB_PERSONAL_ACCESS_TOKEN: ${{ secrets.CYPRESS_GITHUB_PERSONAL_ACCESS_TOKEN }} + CYPRESS_TEST_GITHUB_USER_NAME: ${{ secrets.CYPRESS_TEST_GITHUB_USER_NAME }} + APPSMITH_DISABLE_TELEMETRY: true + APPSMITH_GOOGLE_MAPS_API_KEY: ${{ secrets.APPSMITH_GOOGLE_MAPS_API_KEY }} + COMMIT_INFO_MESSAGE: ${{ github.event.pull_request.title }} + with: + browser: chrome + headless: true + record: true + install: false + parallel: true + config-file: cypress_fat.json + group: "Electrons on Github Action" + spec: ${{ env.failed_spec_env }} + working-directory: app/client + # tag will be either "push" or "pull_request" + tag: ${{ github.event_name }} + env: "NODE_ENV=development" + + # Set status = failedtest + - name: Set fail if there are test failures + if: failure() + run: echo "::set-output name=run_result::failedtest" > ~/run_result + + # Create a directory ~/failed_spec and add a dummy file + # This will ensure upload and download steps are successfull + - name: Create direcotrs for failed tests + if: always() + run: | + mkdir -p ~/failed_spec + echo "empty" >> ~/failed_spec/dummy-${{ matrix.job }} + + # add list failed tests to a file + - name: Incase of test failures copy them to a file + if: failure() + run: | + cd ${{ github.workspace }}/app/client/cypress/ + find screenshots -type d|grep -i spec |sed 's/screenshots/cypress\/integration/g' > ~/failed_spec/failed_spec-${{ matrix.job }} + + # Upload failed test list using common path for all matrix job + - name: Upload failed test list artifact + if: always() + uses: actions/upload-artifact@v2 + with: + name: failed-spec + path: ~/failed_spec + + # Force store previous run result to cache + - name: Store the previous run result + if: failure() + uses: martijnhols/actions-cache/save@v3 + with: + path: | + ~/run_result + key: ${{ github.run_id }}-${{ github.job }}-${{ steps.timestamp.outputs.timestamp }}-${{ matrix.job }} + restore-keys: | + ${{ github.run_id }}-${{ github.job }}-${{ matrix.job }} + + # Force store previous failed test list to cache + - name: Store the previous failed test result + if: failure() + uses: martijnhols/actions-cache/save@v3 + with: + path: | + ~/failed_spec + key: ${{ github.run_id }}-${{ github.job }}-${{ steps.timestamp.outputs.timestamp }}-${{ matrix.job }} + restore-keys: | + ${{ github.run_id }}-${{ github.job }}-${{ matrix.job }} + + # Upload the screenshots as artifacts if there's a failure + - uses: actions/upload-artifact@v1 + if: failure() + with: + name: cypress-screenshots-${{ matrix.job }} + path: app/client/cypress/screenshots/ + + - name: Restore the previous bundle + uses: actions/cache@v2 + with: + path: | + app/client/cypress/snapshots/ + key: ${{ github.run_id }}-${{ github.job }}-${{ steps.timestamp.outputs.timestamp }}-${{ matrix.job }} + restore-keys: | + ${{ github.run_id }}-${{ github.job }}-${{ matrix.job }} + + # Upload the snapshots as artifacts for layout validation + - uses: actions/upload-artifact@v1 + with: + name: cypress-snapshots-visualRegression + path: app/client/cypress/snapshots/ + + # Upload the log artifact so that it can be used by the test & deploy job in the workflow + - name: Upload server logs bundle on failure + uses: actions/upload-artifact@v2 + if: failure() + with: + name: server-logs-${{ matrix.job }} + path: app/server/server-logs.log + + # Set status = success + - run: echo "::set-output name=run_result::success" > ~/run_result + ui-test: needs: [buildClient, buildServer, buildRts] # Only run if the build step is successful @@ -605,7 +944,7 @@ jobs: # Install all the dependencies - name: Install dependencies if: steps.run_result.outputs.run_result != 'success' - run: yarn install + run: yarn install --frozen-lockfile - name: Download the react build artifact if: steps.run_result.outputs.run_result != 'success' diff --git a/Dockerfile b/Dockerfile index 9d9d7c88d8..f5abba4cdb 100644 --- a/Dockerfile +++ b/Dockerfile @@ -91,6 +91,5 @@ ENV PATH /opt/appsmith/utils/node_modules/.bin:$PATH EXPOSE 80 EXPOSE 443 -EXPOSE 9001 ENTRYPOINT [ "/opt/appsmith/entrypoint.sh" ] CMD ["/usr/bin/supervisord", "-n"] diff --git a/README.md b/README.md index a8f562ba6d..58714b7060 100644 --- a/README.md +++ b/README.md @@ -196,6 +196,7 @@ We love our contributors! We're committed to fostering an open and welcoming env
Preet Sidhu

💻 🐛 +
Pallav Agarwal

💻 🐛 diff --git a/app.json b/app.json index 800c130b0b..50e052fe39 100644 --- a/app.json +++ b/app.json @@ -36,6 +36,10 @@ "APPSMITH_DISABLE_TELEMETRY": { "description" : "We want to be transparent and request that you share anonymous usage data with us. This data is purely statistical in nature and helps us understand your needs & provide better support to your self-hosted instance. You can read more about what information is collected in our documentation https://docs.appsmith.com/v/v1.2.1/setup/telemetry", "value": "false" - } + }, + "APPSMITH_SUPERVISOR_PASSWORD": { + "description": "Basic authentication password to access Supervisor UI - An web interface, which allow you to manage various process", + "value": "" + } } } diff --git a/app/client/cypress.json b/app/client/cypress.json index 23d785228c..08980d61de 100644 --- a/app/client/cypress.json +++ b/app/client/cypress.json @@ -20,7 +20,7 @@ "**/Smoke_TestSuite/ClientSideTests/Templates/Fork_Template_spec.js" ], "chromeWebSecurity": false, - "viewportHeight": 900, + "viewportHeight": 1100, "viewportWidth": 1400, "retries": { "runMode": 2, diff --git a/app/client/cypress/fixtures/ButtonGroup_MenuButton_Width_dsl.json b/app/client/cypress/fixtures/ButtonGroup_MenuButton_Width_dsl.json new file mode 100644 index 0000000000..3168a243d3 --- /dev/null +++ b/app/client/cypress/fixtures/ButtonGroup_MenuButton_Width_dsl.json @@ -0,0 +1,326 @@ +{ + "dsl": { + "widgetName": "MainContainer", + "backgroundColor": "none", + "rightColumn": 1160, + "snapColumns": 64, + "detachFromLayout": true, + "widgetId": "0", + "topRow": 0, + "bottomRow": 680, + "containerStyle": "none", + "snapRows": 125, + "parentRowSpace": 1, + "type": "CANVAS_WIDGET", + "canExtend": true, + "version": 54, + "minHeight": 690, + "parentColumnSpace": 1, + "dynamicBindingPathList": [], + "leftColumn": 0, + "children": [ + { + "widgetName": "ButtonGroup1", + "orientation": "horizontal", + "rightColumn": 50, + "isCanvas": false, + "displayName": "Button Group", + "iconSVG": "/static/media/icon.d6773218.svg", + "widgetId": "t5l24fccio", + "topRow": 15, + "bottomRow": 19, + "parentRowSpace": 10, + "isVisible": true, + "groupButtons": { + "groupButton1": { + "label": "Favorite", + "iconName": "heart", + "id": "groupButton1", + "widgetId": "", + "buttonColor": "#03B365", + "buttonType": "SIMPLE", + "placement": "CENTER", + "isVisible": true, + "isDisabled": false, + "index": 0, + "menuItems": {} + }, + "groupButton2": { + "label": "Add", + "iconName": "add", + "id": "groupButton2", + "buttonColor": "#03B365", + "buttonType": "SIMPLE", + "placement": "CENTER", + "widgetId": "", + "isVisible": true, + "isDisabled": false, + "index": 1, + "menuItems": {} + }, + "groupButton3": { + "label": "More", + "iconName": "more", + "id": "groupButton3", + "buttonType": "MENU", + "placement": "CENTER", + "buttonColor": "#03B365", + "widgetId": "", + "isVisible": true, + "isDisabled": false, + "index": 2, + "menuItems": { + "menuItem1": { + "label": "First Option", + "backgroundColor": "#FFFFFF", + "id": "menuItem1", + "widgetId": "", + "onClick": "", + "isVisible": true, + "isDisabled": false, + "index": 0 + }, + "menuItem2": { + "label": "Second Option", + "backgroundColor": "#FFFFFF", + "id": "menuItem2", + "widgetId": "", + "onClick": "", + "isVisible": true, + "isDisabled": false, + "index": 1 + }, + "menuItem3": { + "label": "Delete", + "iconName": "trash", + "iconColor": "#FFFFFF", + "iconAlign": "right", + "textColor": "#FFFFFF", + "backgroundColor": "#DD4B34", + "id": "menuItem3", + "widgetId": "", + "onClick": "", + "isVisible": true, + "isDisabled": false, + "index": 2 + } + } + } + }, + "type": "BUTTON_GROUP_WIDGET", + "version": 1, + "hideCard": false, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "animateLoading": true, + "parentColumnSpace": 17.9375, + "leftColumn": 1, + "buttonVariant": "PRIMARY", + "key": "qxtmv7r8yb" + }, + { + "widgetName": "ButtonGroup2", + "orientation": "horizontal", + "rightColumn": 25, + "isCanvas": false, + "displayName": "Button Group", + "iconSVG": "/static/media/icon.d6773218.svg", + "widgetId": "yxjq5sck7d", + "topRow": 4, + "bottomRow": 8, + "parentRowSpace": 10, + "isVisible": true, + "groupButtons": { + "groupButton1": { + "label": "Favorite", + "iconName": "heart", + "id": "groupButton1", + "widgetId": "", + "buttonColor": "#03B365", + "buttonType": "SIMPLE", + "placement": "CENTER", + "isVisible": true, + "isDisabled": false, + "index": 0, + "menuItems": {} + }, + "groupButton2": { + "label": "Add", + "iconName": "add", + "id": "groupButton2", + "buttonColor": "#03B365", + "buttonType": "SIMPLE", + "placement": "CENTER", + "widgetId": "", + "isVisible": true, + "isDisabled": false, + "index": 1, + "menuItems": {} + }, + "groupButton3": { + "label": "More", + "iconName": "more", + "id": "groupButton3", + "buttonType": "MENU", + "placement": "CENTER", + "buttonColor": "#03B365", + "widgetId": "", + "isVisible": true, + "isDisabled": false, + "index": 2, + "menuItems": { + "menuItem1": { + "label": "First Option", + "backgroundColor": "#FFFFFF", + "id": "menuItem1", + "widgetId": "", + "onClick": "", + "isVisible": true, + "isDisabled": false, + "index": 0 + }, + "menuItem2": { + "label": "Second Option", + "backgroundColor": "#FFFFFF", + "id": "menuItem2", + "widgetId": "", + "onClick": "", + "isVisible": true, + "isDisabled": false, + "index": 1 + }, + "menuItem3": { + "label": "Delete", + "iconName": "trash", + "iconColor": "#FFFFFF", + "iconAlign": "right", + "textColor": "#FFFFFF", + "backgroundColor": "#DD4B34", + "id": "menuItem3", + "widgetId": "", + "onClick": "", + "isVisible": true, + "isDisabled": false, + "index": 2 + } + } + } + }, + "type": "BUTTON_GROUP_WIDGET", + "version": 1, + "hideCard": false, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "animateLoading": true, + "parentColumnSpace": 17.9375, + "leftColumn": 1, + "buttonVariant": "PRIMARY", + "key": "qxtmv7r8yb" + }, + { + "widgetName": "ButtonGroup3", + "isCanvas": false, + "displayName": "Button Group", + "iconSVG": "/static/media/icon.d6773218.svg", + "topRow": 29, + "bottomRow": 55, + "parentRowSpace": 10, + "groupButtons": { + "groupButton1": { + "label": "Favorite", + "iconName": "heart", + "id": "groupButton1", + "widgetId": "", + "buttonColor": "#03B365", + "buttonType": "SIMPLE", + "placement": "CENTER", + "isVisible": true, + "isDisabled": false, + "index": 0, + "menuItems": {} + }, + "groupButton2": { + "label": "Add", + "iconName": "add", + "id": "groupButton2", + "buttonColor": "#03B365", + "buttonType": "SIMPLE", + "placement": "CENTER", + "widgetId": "", + "isVisible": true, + "isDisabled": false, + "index": 1, + "menuItems": {} + }, + "groupButton3": { + "label": "More", + "iconName": "more", + "id": "groupButton3", + "buttonType": "MENU", + "placement": "CENTER", + "buttonColor": "#03B365", + "widgetId": "", + "isVisible": true, + "isDisabled": false, + "index": 2, + "menuItems": { + "menuItem1": { + "label": "First Option", + "backgroundColor": "#FFFFFF", + "id": "menuItem1", + "widgetId": "", + "onClick": "", + "isVisible": true, + "isDisabled": false, + "index": 0 + }, + "menuItem2": { + "label": "Second Option", + "backgroundColor": "#FFFFFF", + "id": "menuItem2", + "widgetId": "", + "onClick": "", + "isVisible": true, + "isDisabled": false, + "index": 1 + }, + "menuItem3": { + "label": "Delete", + "iconName": "trash", + "iconColor": "#FFFFFF", + "iconAlign": "right", + "textColor": "#FFFFFF", + "backgroundColor": "#DD4B34", + "id": "menuItem3", + "widgetId": "", + "onClick": "", + "isVisible": true, + "isDisabled": false, + "index": 2 + } + } + } + }, + "type": "BUTTON_GROUP_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 17.9375, + "dynamicTriggerPathList": [], + "leftColumn": 1, + "dynamicBindingPathList": [], + "key": "qxtmv7r8yb", + "orientation": "horizontal", + "rightColumn": 50, + "widgetId": "mr048y04aq", + "isVisible": true, + "version": 1, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "buttonVariant": "PRIMARY" + } + ] + } +} \ No newline at end of file diff --git a/app/client/cypress/fixtures/InputWidgetV2InsideListDSL.json b/app/client/cypress/fixtures/InputWidgetV2InsideListDSL.json new file mode 100644 index 0000000000..2fe537602b --- /dev/null +++ b/app/client/cypress/fixtures/InputWidgetV2InsideListDSL.json @@ -0,0 +1,327 @@ +{ + "dsl":{ + "widgetName":"MainContainer", + "backgroundColor":"none", + "rightColumn":816, + "snapColumns":64, + "detachFromLayout":true, + "widgetId":"0", + "topRow":0, + "bottomRow":270, + "containerStyle":"none", + "snapRows":125, + "parentRowSpace":1, + "type":"CANVAS_WIDGET", + "canExtend":true, + "version":53, + "minHeight":280, + "parentColumnSpace":1, + "dynamicBindingPathList":[ + + ], + "leftColumn":0, + "children":[ + { + "template":{ + "Input1":{ + "isVisible":true, + "label":"", + "widgetName":"Input1", + "version":2, + "defaultText":"", + "iconAlign":"left", + "autoFocus":false, + "labelStyle":"", + "resetOnSubmit":true, + "isRequired":false, + "isDisabled":false, + "animateLoading":true, + "inputType":"TEXT", + "type":"INPUT_WIDGET_V2", + "hideCard":false, + "displayName":"Input", + "key":"ccm4k3q41x", + "iconSVG":"/static/media/icon.9f505595.svg", + "widgetId":"u0sc4bf6lg", + "renderMode":"CANVAS", + "isLoading":false, + "parentColumnSpace":7.0859375, + "parentRowSpace":10, + "leftColumn":38, + "rightColumn":58, + "topRow":2, + "bottomRow":6, + "parentId":"31i770948x", + "logBlackList":{ + "isVisible":true, + "label":true, + "widgetName":true, + "version":true, + "defaultText":true, + "iconAlign":true, + "autoFocus":true, + "labelStyle":true, + "resetOnSubmit":true, + "isRequired":true, + "isDisabled":true, + "animateLoading":true, + "inputType":true, + "type":true, + "hideCard":true, + "displayName":true, + "key":true, + "iconSVG":true, + "isCanvas":true, + "minHeight":true, + "widgetId":true, + "renderMode":true, + "isLoading":true, + "parentColumnSpace":true, + "parentRowSpace":true, + "leftColumn":true, + "rightColumn":true, + "topRow":true, + "bottomRow":true, + "parentId":true + } + } + }, + "widgetName":"List1", + "listData":[ + { + "id":"001", + "name":"Blue", + "img":"https://assets.appsmith.com/widgets/default.png" + }, + { + "id":"002", + "name":"Green", + "img":"https://assets.appsmith.com/widgets/default.png" + }, + { + "id":"003", + "name":"Red", + "img":"https://assets.appsmith.com/widgets/default.png" + } + ], + "isCanvas":true, + "displayName":"List", + "iconSVG":"/static/media/icon.9925ee17.svg", + "topRow":3, + "bottomRow":20, + "parentRowSpace":10, + "type":"LIST_WIDGET", + "hideCard":false, + "gridGap":0, + "animateLoading":true, + "parentColumnSpace":20.0625, + "dynamicTriggerPathList":[ + + ], + "leftColumn":3, + "dynamicBindingPathList":[ + + ], + "gridType":"vertical", + "enhancements":true, + "children":[ + { + "widgetName":"Canvas1", + "displayName":"Canvas", + "topRow":0, + "bottomRow":400, + "parentRowSpace":1, + "type":"CANVAS_WIDGET", + "canExtend":false, + "hideCard":true, + "dropDisabled":true, + "openParentPropertyPane":true, + "minHeight":400, + "noPad":true, + "parentColumnSpace":1, + "leftColumn":0, + "children":[ + { + "boxShadow":"NONE", + "widgetName":"Container1", + "borderColor":"transparent", + "disallowCopy":true, + "isCanvas":true, + "displayName":"Container", + "iconSVG":"/static/media/icon.1977dca3.svg", + "topRow":0, + "bottomRow":12, + "dragDisabled":true, + "type":"CONTAINER_WIDGET", + "hideCard":false, + "openParentPropertyPane":true, + "isDeletable":false, + "animateLoading":true, + "leftColumn":0, + "children":[ + { + "widgetName":"Canvas2", + "detachFromLayout":true, + "displayName":"Canvas", + "widgetId":"31i770948x", + "containerStyle":"none", + "topRow":0, + "bottomRow":80, + "parentRowSpace":1, + "isVisible":true, + "type":"CANVAS_WIDGET", + "canExtend":false, + "version":1, + "hideCard":true, + "parentId":"wop20uagxv", + "renderMode":"CANVAS", + "isLoading":false, + "parentColumnSpace":1, + "leftColumn":0, + "children":[ + { + "widgetName":"Input1", + "displayName":"Input", + "iconSVG":"/static/media/icon.9f505595.svg", + "topRow":2, + "bottomRow":6, + "parentRowSpace":10, + "autoFocus":false, + "type":"INPUT_WIDGET_V2", + "hideCard":false, + "animateLoading":true, + "parentColumnSpace":7.0859375, + "resetOnSubmit":true, + "leftColumn":4, + "labelStyle":"", + "inputType":"TEXT", + "isDisabled":false, + "key":"ccm4k3q41x", + "isRequired":false, + "rightColumn":60, + "widgetId":"u0sc4bf6lg", + "logBlackList":{ + "isVisible":true, + "label":true, + "widgetName":true, + "version":true, + "defaultText":true, + "iconAlign":true, + "autoFocus":true, + "labelStyle":true, + "resetOnSubmit":true, + "isRequired":true, + "isDisabled":true, + "animateLoading":true, + "inputType":true, + "type":true, + "hideCard":true, + "displayName":true, + "key":true, + "iconSVG":true, + "isCanvas":true, + "minHeight":true, + "widgetId":true, + "renderMode":true, + "isLoading":true, + "parentColumnSpace":true, + "parentRowSpace":true, + "leftColumn":true, + "rightColumn":true, + "topRow":true, + "bottomRow":true, + "parentId":true + }, + "isVisible":true, + "label":"", + "version":2, + "parentId":"31i770948x", + "renderMode":"CANVAS", + "isLoading":false, + "iconAlign":"left", + "defaultText":"" + } + ], + "key":"v48l5zt2p7" + } + ], + "borderWidth":"0", + "key":"w7zaemmrn8", + "disablePropertyPane":true, + "backgroundColor":"white", + "rightColumn":64, + "widgetId":"wop20uagxv", + "containerStyle":"card", + "isVisible":true, + "version":1, + "parentId":"nzmybzveu8", + "renderMode":"CANVAS", + "isLoading":false, + "borderRadius":"0" + } + ], + "key":"v48l5zt2p7", + "rightColumn":481.5, + "detachFromLayout":true, + "widgetId":"nzmybzveu8", + "containerStyle":"none", + "isVisible":true, + "version":1, + "parentId":"78m8pd80bu", + "renderMode":"CANVAS", + "isLoading":false + } + ], + "privateWidgets":{ + "Input1":true + }, + "key":"ns0yjeaevj", + "backgroundColor":"transparent", + "rightColumn":39, + "itemBackgroundColor":"#FFFFFF", + "widgetId":"78m8pd80bu", + "isVisible":true, + "parentId":"0", + "renderMode":"CANVAS", + "isLoading":false + }, + { + "widgetName":"Text3", + "displayName":"Text", + "iconSVG":"/static/media/icon.97c59b52.svg", + "topRow":6, + "bottomRow":15, + "parentRowSpace":10, + "type":"TEXT_WIDGET", + "hideCard":false, + "animateLoading":true, + "parentColumnSpace":20.0625, + "dynamicTriggerPathList":[ + + ], + "leftColumn":43, + "dynamicBindingPathList":[ + { + "key":"text" + } + ], + "shouldTruncate":false, + "truncateButtonColor":"#FFC13D", + "text":"{{List1.items[0].Input1.text}}:{{List1.items[0].Input1.isVisible}}:{{List1.items[0].Input1.isDisabled}}", + "key":"pl30s9buf7", + "rightColumn":59, + "textAlign":"LEFT", + "widgetId":"3ipmljkgo1", + "isVisible":true, + "fontStyle":"BOLD", + "textColor":"#231F20", + "shouldScroll":false, + "version":1, + "parentId":"0", + "renderMode":"CANVAS", + "isLoading":false, + "fontSize":"PARAGRAPH" + } + ] + } +} \ No newline at end of file diff --git a/app/client/cypress/fixtures/buttonRecaptchaDsl.json b/app/client/cypress/fixtures/buttonRecaptchaDsl.json new file mode 100644 index 0000000000..b5605cdd56 --- /dev/null +++ b/app/client/cypress/fixtures/buttonRecaptchaDsl.json @@ -0,0 +1,87 @@ +{ + "dsl": { + "widgetName": "MainContainer", + "backgroundColor": "none", + "rightColumn": 1056, + "snapColumns": 64, + "detachFromLayout": true, + "widgetId": "0", + "topRow": 0, + "bottomRow": 800, + "containerStyle": "none", + "snapRows": 125, + "parentRowSpace": 1, + "type": "CANVAS_WIDGET", + "canExtend": true, + "version": 52, + "minHeight": 780, + "parentColumnSpace": 1, + "dynamicBindingPathList": [], + "leftColumn": 0, + "children": [ + { + "isVisible": true, + "animateLoading": true, + "text": "Submit", + "buttonColor": "#03B365", + "buttonVariant": "PRIMARY", + "placement": "CENTER", + "widgetName": "Button1", + "isDisabled": false, + "isDefaultClickDisabled": true, + "recaptchaType": "V3", + "version": 1, + "type": "BUTTON_WIDGET", + "hideCard": false, + "displayName": "Button", + "key": "b3xxd5tj9s", + "iconSVG": "/static/media/icon.cca02633.svg", + "widgetId": "56yla62kkw", + "renderMode": "CANVAS", + "isLoading": false, + "parentColumnSpace": 16.3125, + "parentRowSpace": 10, + "leftColumn": 19, + "rightColumn": 35, + "topRow": 10, + "bottomRow": 14, + "parentId": "0" + }, + { + "isVisible": true, + "text": "{{Button1.recaptchaToken}}", + "fontSize": "PARAGRAPH", + "fontStyle": "BOLD", + "textAlign": "LEFT", + "textColor": "#231F20", + "truncateButtonColor": "#FFC13D", + "widgetName": "Text1", + "shouldScroll": false, + "shouldTruncate": false, + "version": 1, + "animateLoading": true, + "type": "TEXT_WIDGET", + "hideCard": false, + "displayName": "Text", + "key": "6cg9oqz0if", + "iconSVG": "/static/media/icon.97c59b52.svg", + "widgetId": "iymasdikx5", + "renderMode": "CANVAS", + "isLoading": false, + "parentColumnSpace": 16.3125, + "parentRowSpace": 10, + "leftColumn": 19, + "rightColumn": 35, + "topRow": 26, + "bottomRow": 30, + "parentId": "0", + "dynamicBindingPathList": [ + { + "key": "text" + } + ], + "dynamicTriggerPathList": [] + } + ] + } +} \ No newline at end of file diff --git a/app/client/cypress/fixtures/datasources.json b/app/client/cypress/fixtures/datasources.json index cd7de82f95..8c92bd6cbe 100644 --- a/app/client/cypress/fixtures/datasources.json +++ b/app/client/cypress/fixtures/datasources.json @@ -44,5 +44,6 @@ "mockDatabaseName": "fakeapi", "mockDatabaseUsername": "fakeapi", "mockDatabasePassword": "LimitedAccess123#", - "readonly":"readonly" + "readonly":"readonly", + "authenticatedApiUrl": "https://fakeapi.com" } diff --git a/app/client/cypress/fixtures/exported-app.json b/app/client/cypress/fixtures/exported-app.json index 8426723b86..f7c04f500d 100644 --- a/app/client/cypress/fixtures/exported-app.json +++ b/app/client/cypress/fixtures/exported-app.json @@ -1,19 +1,15 @@ { + "clientSchemaVersion": 1, + "serverSchemaVersion": 1, "exportedApplication": { - "userPermissions": [ - "canComment:applications", - "manage:applications", - "export:applications", - "read:applications", - "publish:applications", - "makePublic:applications" - ], - "name": "2eacca10", + "name": "d85f5e74", "isPublic": false, "appIsExample": false, "unreadCommentThreads": 0, - "color": "#F1DEFF", - "icon": "cat", + "color": "#D9E7FF", + "icon": "cloud", + "slug": "d85f5e74", + "evaluationVersion": 2, "new": true }, "datasourceList": [], @@ -23,12 +19,13 @@ "read:pages", "manage:pages" ], - "gitSyncId": "61602709ae8b022ed53c23c7_2021-10-08T11:10:01.203693Z", + "gitSyncId": "6200c8457d76221d03e360e0_6200c8457d76221d03e360e2", "unpublishedPage": { "name": "Page1", + "slug": "page1", "layouts": [ { - "id": "61602709ae8b022ed53c23c8", + "id": "Page1", "userPermissions": [], "dsl": { "widgetName": "MainContainer", @@ -147,7 +144,7 @@ { "widgetName": "Chart1", "rightColumn": 8, - "allowHorizontalScroll": false, + "allowScroll": false, "widgetId": "hwi9cwhg43", "topRow": 1, "bottomRow": 9, @@ -270,9 +267,10 @@ }, "publishedPage": { "name": "Page1", + "slug": "page1", "layouts": [ { - "id": "61602709ae8b022ed53c23c8", + "id": "Page1", "userPermissions": [], "dsl": { "widgetName": "MainContainer", @@ -308,6 +306,16 @@ "actionList": [], "actionCollectionList": [], "decryptedFields": {}, + "editModeTheme": { + "name": "Classic", + "new": true, + "isSystemTheme": true + }, + "publishedTheme": { + "name": "Classic", + "new": true, + "isSystemTheme": true + }, "publishedLayoutmongoEscapedWidgets": {}, "unpublishedLayoutmongoEscapedWidgets": {} } \ No newline at end of file diff --git a/app/client/cypress/fixtures/exportedApp.json b/app/client/cypress/fixtures/exportedApp.json index cd7f013bba..8026c63d2f 100644 --- a/app/client/cypress/fixtures/exportedApp.json +++ b/app/client/cypress/fixtures/exportedApp.json @@ -1,313 +1,675 @@ { - "exportedApplication": { + "clientSchemaVersion": 1, + "serverSchemaVersion": 2, + "exportedApplication": { + "name": "app2896", + "isPublic": false, + "appIsExample": false, + "unreadCommentThreads": 0, + "color": "#F4FFDE", + "icon": "single-person", + "slug": "app2896", + "evaluationVersion": 2, + "applicationVersion": 2, + "new": true + }, + "datasourceList": [ + { "userPermissions": [ - "canComment:applications", - "manage:applications", - "export:applications", - "read:applications", - "publish:applications", - "makePublic:applications" + "execute:datasources", + "manage:datasources", + "read:datasources" ], - "name": "2eacca10", - "isPublic": false, - "appIsExample": false, - "unreadCommentThreads": 0, - "color": "#F1DEFF", - "icon": "cat", + "gitSyncId": "61c2d94747cda83965fe72b5_61c5822385c0bd4ccf7d171c", + "name": "mockdata", + "pluginId": "postgres-plugin", + "invalids": [ + "Missing authentication details." + ], + "messages": [], + "isConfigured": false, + "isValid": false, "new": true - }, - "datasourceList": [], - "pageList": [ - { - "userPermissions": [ - "read:pages", - "manage:pages" - ], - "gitSyncId": "61602709ae8b022ed53c23c7_2021-10-08T11:10:01.203693Z", - "unpublishedPage": { - "name": "Page1", - "layouts": [ - { - "id": "61602709ae8b022ed53c23c8", - "userPermissions": [], - "dsl": { - "widgetName": "MainContainer", - "backgroundColor": "none", - "rightColumn": 1224, - "snapColumns": 16, - "detachFromLayout": true, - "widgetId": "0", - "topRow": 0, - "bottomRow": 1292, - "containerStyle": "none", - "snapRows": 33, - "parentRowSpace": 1, - "type": "CANVAS_WIDGET", - "canExtend": true, - "minHeight": 1292, - "parentColumnSpace": 1, - "dynamicBindingPathList": [], - "leftColumn": 0, - "children": [ - { - "backgroundColor": "#FFFFFF", - "widgetName": "Container1", - "rightColumn": 8, - "orientation": "VERTICAL", - "snapColumns": 16, - "widgetId": "mxbaasg65u", - "containerStyle": "card", - "topRow": 0, - "bottomRow": 9, - "parentRowSpace": 38, - "isVisible": true, - "type": "CONTAINER_WIDGET", - "isLoading": false, - "parentColumnSpace": 75.25, - "dynamicBindingPathList": [], - "leftColumn": 0, - "children": [ - { - "backgroundColor": "transparent", - "widgetName": "59gdivzv7s", - "rightColumn": 602, - "orientation": "VERTICAL", - "snapColumns": 16, - "detachFromLayout": true, - "widgetId": "bxekwxgc1i", - "containerStyle": "none", - "topRow": 0, - "bottomRow": 342, - "parentRowSpace": 1, - "isVisible": true, - "type": "CANVAS_WIDGET", - "canExtend": false, - "isLoading": false, - "parentColumnSpace": 1, - "leftColumn": 0, - "children": [ - { - "image": "", - "widgetName": "Image1", - "rightColumn": 10, - "widgetId": "glksllew0g", - "topRow": 2, - "bottomRow": 5, - "parentRowSpace": 38, - "isVisible": true, - "type": "IMAGE_WIDGET", - "parentId": "bxekwxgc1i", - "isLoading": false, - "parentColumnSpace": 34.6875, - "imageShape": "RECTANGLE", - "leftColumn": 6, - "defaultImage": "https://res.cloudinary.com/drako999/image/upload/v1589196259/default.png" - } - ] - } - ] + } + ], + "pageList": [ + { + "userPermissions": [ + "read:pages", + "manage:pages" + ], + "gitSyncId": "61c580d685c0bd4ccf7d1716_61c580d685c0bd4ccf7d1718", + "unpublishedPage": { + "name": "Page1", + "slug": "page1", + "layouts": [ + { + "id": "Page1", + "userPermissions": [], + "dsl": { + "widgetName": "MainContainer", + "backgroundColor": "none", + "rightColumn": 816, + "snapColumns": 64, + "detachFromLayout": true, + "widgetId": "0", + "topRow": 0, + "bottomRow": 590, + "containerStyle": "none", + "snapRows": 125, + "parentRowSpace": 1, + "type": "CANVAS_WIDGET", + "canExtend": true, + "version": 52, + "minHeight": 600, + "parentColumnSpace": 1, + "dynamicBindingPathList": [], + "leftColumn": 0, + "children": [ + { + "widgetName": "Table1", + "defaultPageSize": 0, + "columnOrder": [ + "schema_name" + ], + "isVisibleDownload": true, + "dynamicPropertyPathList": [], + "displayName": "Table", + "iconSVG": "/static/media/icon.db8a9cbd.svg", + "topRow": 14, + "bottomRow": 38, + "isSortable": true, + "parentRowSpace": 10, + "type": "TABLE_WIDGET", + "defaultSelectedRow": "0", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 12.5625, + "dynamicTriggerPathList": [], + "dynamicBindingPathList": [ + { + "key": "tableData" + }, + { + "key": "primaryColumns.schema_name.computedValue" + } + ], + "leftColumn": 4, + "primaryColumns": { + "schema_name": { + "index": 0, + "width": 150, + "id": "schema_name", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "text", + "textSize": "PARAGRAPH", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isDisabled": false, + "isCellVisible": true, + "isDerived": false, + "label": "schema_name", + "computedValue": "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.schema_name))}}" + } }, - { - "backgroundColor": "#FFFFFF", - "widgetName": "Container3", - "rightColumn": 16, - "orientation": "VERTICAL", - "snapColumns": 16, - "widgetId": "i331vll2mg", - "containerStyle": "card", - "topRow": 9, - "bottomRow": 23, - "parentRowSpace": 38, - "isVisible": true, - "type": "CONTAINER_WIDGET", - "isLoading": false, - "parentColumnSpace": 75.25, - "dynamicBindingPathList": [], - "leftColumn": 0, - "children": [ - { - "backgroundColor": "transparent", - "widgetName": "rhfg2vf1n5", - "rightColumn": 1204, - "orientation": "VERTICAL", - "snapColumns": 16, - "detachFromLayout": true, - "widgetId": "rglduihhzk", - "containerStyle": "none", - "topRow": 0, - "bottomRow": 532, - "parentRowSpace": 1, - "isVisible": true, - "type": "CANVAS_WIDGET", - "canExtend": false, - "isLoading": false, - "parentColumnSpace": 1, - "leftColumn": 0, - "children": [ - { - "widgetName": "Chart1", - "rightColumn": 8, - "allowHorizontalScroll": false, - "widgetId": "hwi9cwhg43", - "topRow": 1, - "bottomRow": 9, - "parentRowSpace": 38, - "isVisible": true, - "type": "CHART_WIDGET", - "parentId": "rglduihhzk", - "isLoading": false, - "chartData": [ - { - "seriesName": "Sales", - "data": [ - { - "x": "Mon", - "y": 10000 - }, - { - "x": "Tue", - "y": 12000 - }, - { - "x": "Wed", - "y": 32000 - }, - { - "x": "Thu", - "y": 28000 - }, - { - "x": "Fri", - "y": 14000 - }, - { - "x": "Sat", - "y": 19000 - }, - { - "x": "Sun", - "y": 36000 - } - ] - } - ], - "yAxisName": "Total Order Revenue $", - "parentColumnSpace": 71.75, - "chartName": "Sales on working days", - "leftColumn": 2, - "dynamicBindingPathList": [], - "xAxisName": "Last Week", - "chartType": "LINE_CHART" - } - ] - } - ] - }, - { - "backgroundColor": "#FFFFFF", - "widgetName": "Container4", - "rightColumn": 16, - "orientation": "VERTICAL", - "snapColumns": 16, - "widgetId": "qznzsquf70", - "containerStyle": "card", - "topRow": 0, - "bottomRow": 9, - "parentRowSpace": 38, - "isVisible": true, - "type": "CONTAINER_WIDGET", - "isLoading": false, - "parentColumnSpace": 75.25, - "dynamicBindingPathList": [], - "leftColumn": 8, - "children": [ - { - "backgroundColor": "transparent", - "widgetName": "3bn6uv0vy4", - "rightColumn": 602, - "orientation": "VERTICAL", - "snapColumns": 16, - "detachFromLayout": true, - "widgetId": "7vm5mdu8ey", - "containerStyle": "none", - "topRow": 0, - "bottomRow": 342, - "parentRowSpace": 1, - "isVisible": true, - "type": "CANVAS_WIDGET", - "canExtend": false, - "isLoading": false, - "parentColumnSpace": 1, - "leftColumn": 0, - "children": [ - { - "widgetName": "Text1", - "rightColumn": 7, - "textAlign": "LEFT", - "widgetId": "9xcfqahpw2", - "topRow": 3, - "bottomRow": 4, - "parentRowSpace": 38, - "isVisible": true, - "type": "TEXT_WIDGET", - "parentId": "bxekwxgc1i", - "isLoading": false, - "parentColumnSpace": 34.6875, - "leftColumn": 3, - "text": "Label" - } - ] - } - ] + "delimiter": ",", + "key": "5ejs55im17", + "derivedColumns": {}, + "rightColumn": 25, + "textSize": "PARAGRAPH", + "widgetId": "uyyp0qxfdq", + "isVisibleFilters": true, + "tableData": "{{get_schema.data}}", + "isVisible": true, + "label": "Data", + "searchKey": "", + "enableClientSideSearch": true, + "version": 3, + "totalRecordsCount": 0, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "horizontalAlignment": "LEFT", + "isVisibleSearch": true, + "isVisiblePagination": true, + "verticalAlignment": "CENTER", + "columnSizeMap": { + "task": 245, + "step": 62, + "status": 75 } - ] - }, - "layoutOnLoadActions": [], - "new": false - } - ], - "userPermissions": [] + }, + { + "widgetName": "Table2", + "defaultPageSize": 0, + "columnOrder": [ + "id", + "title", + "due", + "assignee" + ], + "isVisibleDownload": true, + "dynamicPropertyPathList": [], + "displayName": "Table", + "iconSVG": "/static/media/icon.db8a9cbd.svg", + "topRow": 14, + "bottomRow": 38, + "isSortable": true, + "parentRowSpace": 10, + "type": "TABLE_WIDGET", + "defaultSelectedRow": "0", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 12.5625, + "dynamicTriggerPathList": [], + "dynamicBindingPathList": [ + { + "key": "tableData" + }, + { + "key": "primaryColumns.due.computedValue" + }, + { + "key": "primaryColumns.assignee.computedValue" + }, + { + "key": "primaryColumns.title.computedValue" + }, + { + "key": "primaryColumns.id.computedValue" + } + ], + "leftColumn": 30, + "primaryColumns": { + "due": { + "index": 0, + "width": 150, + "id": "due", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "text", + "textSize": "PARAGRAPH", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isDisabled": false, + "isCellVisible": true, + "isDerived": false, + "label": "due", + "computedValue": "{{Table2.sanitizedTableData.map((currentRow) => ( currentRow.due))}}" + }, + "assignee": { + "index": 1, + "width": 150, + "id": "assignee", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "text", + "textSize": "PARAGRAPH", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isDisabled": false, + "isCellVisible": true, + "isDerived": false, + "label": "assignee", + "computedValue": "{{Table2.sanitizedTableData.map((currentRow) => ( currentRow.assignee))}}" + }, + "title": { + "index": 2, + "width": 150, + "id": "title", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "text", + "textSize": "PARAGRAPH", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isDisabled": false, + "isCellVisible": true, + "isDerived": false, + "label": "title", + "computedValue": "{{Table2.sanitizedTableData.map((currentRow) => ( currentRow.title))}}" + }, + "id": { + "index": 4, + "width": 150, + "id": "id", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "text", + "textSize": "PARAGRAPH", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isDisabled": false, + "isCellVisible": true, + "isDerived": false, + "label": "id", + "computedValue": "{{Table2.sanitizedTableData.map((currentRow) => ( currentRow.id))}}" + } + }, + "delimiter": ",", + "key": "5ejs55im17", + "derivedColumns": {}, + "rightColumn": 61, + "textSize": "PARAGRAPH", + "widgetId": "r1m4lkt7at", + "isVisibleFilters": true, + "tableData": "{{mockApi.data.headers.info}}", + "isVisible": true, + "label": "Data", + "searchKey": "", + "enableClientSideSearch": true, + "version": 3, + "totalRecordsCount": 0, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "horizontalAlignment": "LEFT", + "isVisibleSearch": true, + "isVisiblePagination": true, + "verticalAlignment": "CENTER", + "columnSizeMap": { + "task": 245, + "step": 62, + "status": 75, + "id": 60 + } + }, + { + "widgetName": "Input1", + "displayName": "Input", + "iconSVG": "/static/media/icon.9f505595.svg", + "topRow": 43, + "bottomRow": 47, + "parentRowSpace": 10, + "autoFocus": false, + "type": "INPUT_WIDGET_V2", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 12.5625, + "dynamicTriggerPathList": [], + "resetOnSubmit": true, + "leftColumn": 18, + "dynamicBindingPathList": [ + { + "key": "defaultText" + } + ], + "labelStyle": "", + "inputType": "TEXT", + "isDisabled": false, + "key": "t02w4ix9o5", + "isRequired": false, + "rightColumn": 38, + "widgetId": "9timcor5m5", + "isVisible": true, + "label": "", + "allowCurrencyChange": false, + "version": 1, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "iconAlign": "left", + "defaultText": "{{JSObject1.myVar1}}" + } + ] + }, + "layoutOnLoadActions": [ + [ + { + "id": "Page1_get_schema", + "name": "get_schema", + "pluginType": "DB", + "jsonPathKeys": [], + "timeoutInMillisecond": 10000 + } + ], + [ + { + "id": "Page1_mockApi", + "name": "mockApi", + "pluginType": "API", + "jsonPathKeys": [], + "timeoutInMillisecond": 10000 + } + ] + ], + "new": false + } + ], + "userPermissions": [] + }, + "publishedPage": { + "name": "Page1", + "slug": "page1", + "layouts": [ + { + "id": "Page1", + "userPermissions": [], + "dsl": { + "widgetName": "MainContainer", + "backgroundColor": "none", + "rightColumn": 1224, + "snapColumns": 16, + "detachFromLayout": true, + "widgetId": "0", + "topRow": 0, + "bottomRow": 1254, + "containerStyle": "none", + "snapRows": 33, + "parentRowSpace": 1, + "type": "CANVAS_WIDGET", + "canExtend": true, + "version": 4, + "minHeight": 1292, + "parentColumnSpace": 1, + "dynamicBindingPathList": [], + "leftColumn": 0, + "children": [] + }, + "new": false + } + ], + "userPermissions": [] + }, + "new": true + } + ], + "publishedDefaultPageName": "Page1", + "unpublishedDefaultPageName": "Page1", + "actionList": [ + { + "id": "Page1_mockApi", + "userPermissions": [ + "read:actions", + "execute:actions", + "manage:actions" + ], + "gitSyncId": "61c580d685c0bd4ccf7d1716_61c580e385c0bd4ccf7d171a", + "pluginType": "API", + "pluginId": "restapi-plugin", + "unpublishedAction": { + "name": "mockApi", + "datasource": { + "userPermissions": [], + "name": "DEFAULT_REST_DATASOURCE", + "pluginId": "restapi-plugin", + "datasourceConfiguration": { + "url": "https://mock-api.appsmith.com" + }, + "invalids": [], + "messages": [], + "isValid": true, + "new": true }, - "publishedPage": { - "name": "Page1", - "layouts": [ + "pageId": "Page1", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "path": "/echo/get", + "headers": [ { - "id": "61602709ae8b022ed53c23c8", - "userPermissions": [], - "dsl": { - "widgetName": "MainContainer", - "backgroundColor": "none", - "rightColumn": 1224, - "snapColumns": 16, - "detachFromLayout": true, - "widgetId": "0", - "topRow": 0, - "bottomRow": 1254, - "containerStyle": "none", - "snapRows": 33, - "parentRowSpace": 1, - "type": "CANVAS_WIDGET", - "canExtend": true, - "version": 4, - "minHeight": 1292, - "parentColumnSpace": 1, - "dynamicBindingPathList": [], - "leftColumn": 0, - "children": [] - }, - "new": false + "key": "info", + "value": "[{\"due\":\"2021-11-23\",\"assignee\":\"Dan.Wyman@hotmail.com\",\"title\":\"Recusan\",\"id\":\"1\"},{\"due\":\"2021-11-23\",\"assignee\":\"Dashawn_Maggio30@gmail.com\",\"title\":\"Dignissimos eaque\",\"id\":\"2\"},{\"due\":\"2021-11-24\",\"assignee\":\"Curt50@gmail.com\",\"title\":\"Voluptas explicabo\",\"id\":\"3\"},{\"due\":\"2021-11-23\",\"assignee\":\"Shanna63@hotmail.com\",\"title\":\"Aut omnis.\",\"id\":\"4\"}]" } ], - "userPermissions": [] + "encodeParamsToggle": true, + "queryParameters": [], + "body": "", + "httpMethod": "GET", + "pluginSpecifiedTemplates": [ + { + "value": true + } + ] }, - "new": true - } - ], - "publishedDefaultPageName": "Page1", - "unpublishedDefaultPageName": "Page1", - "actionList": [], - "actionCollectionList": [], - "decryptedFields": {}, - "publishedLayoutmongoEscapedWidgets": {}, - "unpublishedLayoutmongoEscapedWidgets": {} - } \ No newline at end of file + "executeOnLoad": true, + "dynamicBindingPathList": [], + "isValid": true, + "invalids": [], + "messages": [], + "jsonPathKeys": [], + "confirmBeforeExecute": false, + "userPermissions": [], + "validName": "mockApi" + }, + "publishedAction": { + "datasource": { + "userPermissions": [], + "messages": [], + "isValid": true, + "new": true + }, + "messages": [], + "confirmBeforeExecute": false, + "userPermissions": [] + }, + "new": false + }, + { + "id": "Page1_myFun1", + "userPermissions": [ + "read:actions", + "execute:actions", + "manage:actions" + ], + "gitSyncId": "61c580d685c0bd4ccf7d1716_61c58ced85c0bd4ccf7d1722", + "pluginType": "JS", + "pluginId": "js-plugin", + "unpublishedAction": { + "name": "myFun1", + "fullyQualifiedName": "JSObject1.myFun1", + "datasource": { + "userPermissions": [], + "name": "UNUSED_DATASOURCE", + "pluginId": "js-plugin", + "messages": [], + "isValid": true, + "new": true + }, + "pageId": "Page1", + "collectionId": "Page1_JSObject1", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "encodeParamsToggle": true, + "body": "() => {\n\t\t//write code here\n\t\treturn JSObject1.myVar1;\n\t}", + "jsArguments": [], + "isAsync": false + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { + "key": "body" + } + ], + "isValid": true, + "invalids": [], + "messages": [], + "jsonPathKeys": [ + "() => {\n\t\t//write code here\n\t\treturn JSObject1.myVar1;\n\t}" + ], + "confirmBeforeExecute": false, + "userPermissions": [], + "validName": "JSObject1.myFun1" + }, + "publishedAction": { + "datasource": { + "userPermissions": [], + "messages": [], + "isValid": true, + "new": true + }, + "messages": [], + "confirmBeforeExecute": false, + "userPermissions": [] + }, + "new": false + }, + { + "id": "Page1_get_schema", + "userPermissions": [ + "read:actions", + "execute:actions", + "manage:actions" + ], + "gitSyncId": "61c580d685c0bd4ccf7d1716_61c5832685c0bd4ccf7d171e", + "pluginType": "DB", + "pluginId": "postgres-plugin", + "unpublishedAction": { + "name": "get_schema", + "datasource": { + "id": "mockdata", + "userPermissions": [], + "pluginId": "postgres-plugin", + "messages": [], + "isValid": true, + "new": false + }, + "pageId": "Page1", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "encodeParamsToggle": true, + "body": "SELECT schema_name FROM information_schema.schemata;", + "pluginSpecifiedTemplates": [ + { + "value": true + } + ] + }, + "executeOnLoad": true, + "dynamicBindingPathList": [], + "isValid": true, + "invalids": [], + "messages": [], + "jsonPathKeys": [], + "confirmBeforeExecute": false, + "userPermissions": [], + "validName": "get_schema" + }, + "publishedAction": { + "datasource": { + "userPermissions": [], + "messages": [], + "isValid": true, + "new": true + }, + "messages": [], + "confirmBeforeExecute": false, + "userPermissions": [] + }, + "new": false + }, + { + "id": "Page1_myFun2", + "userPermissions": [ + "read:actions", + "execute:actions", + "manage:actions" + ], + "gitSyncId": "61c580d685c0bd4ccf7d1716_61c58ced85c0bd4ccf7d1724", + "pluginType": "JS", + "pluginId": "js-plugin", + "unpublishedAction": { + "name": "myFun2", + "fullyQualifiedName": "JSObject1.myFun2", + "datasource": { + "userPermissions": [], + "name": "UNUSED_DATASOURCE", + "pluginId": "js-plugin", + "messages": [], + "isValid": true, + "new": true + }, + "pageId": "Page1", + "collectionId": "Page1_JSObject1", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "encodeParamsToggle": true, + "body": "() => {\n\t\t//write code here\n\t}", + "jsArguments": [], + "isAsync": false + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { + "key": "body" + } + ], + "isValid": true, + "invalids": [], + "messages": [], + "jsonPathKeys": [ + "() => {\n\t\t//write code here\n\t}" + ], + "confirmBeforeExecute": false, + "userPermissions": [], + "validName": "JSObject1.myFun2" + }, + "publishedAction": { + "datasource": { + "userPermissions": [], + "messages": [], + "isValid": true, + "new": true + }, + "messages": [], + "confirmBeforeExecute": false, + "userPermissions": [] + }, + "new": false + } + ], + "actionCollectionList": [ + { + "id": "Page1_JSObject1", + "userPermissions": [ + "read:actions", + "execute:actions", + "manage:actions" + ], + "gitSyncId": "61c580d685c0bd4ccf7d1716_61c58ced85c0bd4ccf7d1726", + "unpublishedCollection": { + "name": "JSObject1", + "pageId": "Page1", + "pluginId": "js-plugin", + "pluginType": "JS", + "actionIds": [], + "archivedActionIds": [], + "actions": [], + "archivedActions": [], + "body": "export default {\n\tmyVar1: \"Submit\",\n\tmyVar2: {},\n\tmyFun1: () => {\n\t\t//write code here\n\t\treturn this.myVar1;\n\t},\n\tmyFun2: () => {\n\t\t//write code here\n\t}\n}", + "variables": [ + { + "name": "myVar1", + "value": "Submit" + }, + { + "name": "myVar2", + "value": {} + } + ] + }, + "new": false + } + ], + "editModeTheme": { + "name": "Classic", + "new": true, + "isSystemTheme": true + }, + "publishedTheme": { + "name": "Classic", + "new": true, + "isSystemTheme": true + }, + "publishedLayoutmongoEscapedWidgets": {}, + "unpublishedLayoutmongoEscapedWidgets": {} +} \ No newline at end of file diff --git a/app/client/cypress/fixtures/forkedApp.json b/app/client/cypress/fixtures/forkedApp.json index daa3aec2ec..f933a588e4 100644 --- a/app/client/cypress/fixtures/forkedApp.json +++ b/app/client/cypress/fixtures/forkedApp.json @@ -1,697 +1,698 @@ { - "clientSchemaVersion": 1, - "serverSchemaVersion": 1, - "exportedApplication": { - "name": "app", - "isPublic": false, - "appIsExample": false, - "unreadCommentThreads": 0, - "color": "#F4FFDE", - "icon": "single-person", - "slug": "app", - "evaluationVersion": 2, + "clientSchemaVersion": 1, + "serverSchemaVersion": 1, + "exportedApplication": { + "name": "app", + "isPublic": false, + "appIsExample": false, + "unreadCommentThreads": 0, + "color": "#F4FFDE", + "icon": "single-person", + "slug": "app", + "evaluationVersion": 2, + "applicationVersion": 2, + "new": true + }, + "datasourceList": [ + { + "userPermissions": [ + "execute:datasources", + "manage:datasources", + "read:datasources" + ], + "gitSyncId": "61c2d94747cda83965fe72b5_61c5822385c0bd4ccf7d171c", + "name": "mockdata", + "pluginId": "postgres-plugin", + "datasourceConfiguration": { + "connection": { + "mode": "READ_WRITE", + "ssl": { + "authType": "DEFAULT" + } + }, + "endpoints": [ + { + "host": "localhost", + "port": 5432 + } + ], + "sshProxyEnabled": false + }, + "invalids": [], + "messages": [], + "isValid": true, "new": true - }, - "datasourceList": [ - { - "userPermissions": [ - "execute:datasources", - "manage:datasources", - "read:datasources" - ], - "gitSyncId": "61c2d94747cda83965fe72b5_61c5822385c0bd4ccf7d171c", - "name": "mockdata", - "pluginId": "postgres-plugin", - "datasourceConfiguration": { - "connection": { - "mode": "READ_WRITE", - "ssl": { - "authType": "DEFAULT" - } - }, - "endpoints": [ - { - "host": "localhost", - "port": 5432 - } - ], - "sshProxyEnabled": false - }, - "invalids": [], - "messages": [], - "isValid": true, - "new": true - } - ], - "pageList": [ - { - "userPermissions": [ - "read:pages", - "manage:pages" - ], - "gitSyncId": "61c580d685c0bd4ccf7d1716_61c580d685c0bd4ccf7d1718", - "unpublishedPage": { - "name": "Page1", - "slug": "page1", - "layouts": [ - { - "id": "Page1", - "userPermissions": [], - "dsl": { - "widgetName": "MainContainer", - "backgroundColor": "none", - "rightColumn": 816, - "snapColumns": 64, - "detachFromLayout": true, - "widgetId": "0", - "topRow": 0, - "bottomRow": 590, - "containerStyle": "none", - "snapRows": 125, - "parentRowSpace": 1, - "type": "CANVAS_WIDGET", - "canExtend": true, - "version": 52, - "minHeight": 600, - "parentColumnSpace": 1, - "dynamicBindingPathList": [], - "leftColumn": 0, - "children": [ - { - "widgetName": "Table1", - "defaultPageSize": 0, - "columnOrder": [ - "schema_name" - ], - "isVisibleDownload": true, - "dynamicPropertyPathList": [], - "displayName": "Table", - "iconSVG": "/static/media/icon.db8a9cbd.svg", - "topRow": 14, - "bottomRow": 38, - "isSortable": true, - "parentRowSpace": 10, - "type": "TABLE_WIDGET", - "defaultSelectedRow": "0", - "hideCard": false, - "animateLoading": true, - "parentColumnSpace": 12.5625, - "dynamicTriggerPathList": [], - "dynamicBindingPathList": [ - { - "key": "tableData" - }, - { - "key": "primaryColumns.schema_name.computedValue" - } - ], - "leftColumn": 4, - "primaryColumns": { - "schema_name": { - "index": 0, - "width": 150, - "id": "schema_name", - "horizontalAlignment": "LEFT", - "verticalAlignment": "CENTER", - "columnType": "text", - "textSize": "PARAGRAPH", - "enableFilter": true, - "enableSort": true, - "isVisible": true, - "isDisabled": false, - "isCellVisible": true, - "isDerived": false, - "label": "schema_name", - "computedValue": "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.schema_name))}}" - } + } + ], + "pageList": [ + { + "userPermissions": [ + "read:pages", + "manage:pages" + ], + "gitSyncId": "61c580d685c0bd4ccf7d1716_61c580d685c0bd4ccf7d1718", + "unpublishedPage": { + "name": "Page1", + "slug": "page1", + "layouts": [ + { + "id": "Page1", + "userPermissions": [], + "dsl": { + "widgetName": "MainContainer", + "backgroundColor": "none", + "rightColumn": 816, + "snapColumns": 64, + "detachFromLayout": true, + "widgetId": "0", + "topRow": 0, + "bottomRow": 590, + "containerStyle": "none", + "snapRows": 125, + "parentRowSpace": 1, + "type": "CANVAS_WIDGET", + "canExtend": true, + "version": 52, + "minHeight": 600, + "parentColumnSpace": 1, + "dynamicBindingPathList": [], + "leftColumn": 0, + "children": [ + { + "widgetName": "Table1", + "defaultPageSize": 0, + "columnOrder": [ + "schema_name" + ], + "isVisibleDownload": true, + "dynamicPropertyPathList": [], + "displayName": "Table", + "iconSVG": "/static/media/icon.db8a9cbd.svg", + "topRow": 14, + "bottomRow": 38, + "isSortable": true, + "parentRowSpace": 10, + "type": "TABLE_WIDGET", + "defaultSelectedRow": "0", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 12.5625, + "dynamicTriggerPathList": [], + "dynamicBindingPathList": [ + { + "key": "tableData" }, - "delimiter": ",", - "key": "5ejs55im17", - "derivedColumns": {}, - "rightColumn": 25, - "textSize": "PARAGRAPH", - "widgetId": "uyyp0qxfdq", - "isVisibleFilters": true, - "tableData": "{{get_schema.data}}", - "isVisible": true, - "label": "Data", - "searchKey": "", - "enableClientSideSearch": true, - "version": 3, - "totalRecordsCount": 0, - "parentId": "0", - "renderMode": "CANVAS", - "isLoading": false, - "horizontalAlignment": "LEFT", - "isVisibleSearch": true, - "isVisiblePagination": true, - "verticalAlignment": "CENTER", - "columnSizeMap": { - "task": 245, - "step": 62, - "status": 75 + { + "key": "primaryColumns.schema_name.computedValue" + } + ], + "leftColumn": 4, + "primaryColumns": { + "schema_name": { + "index": 0, + "width": 150, + "id": "schema_name", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "text", + "textSize": "PARAGRAPH", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isDisabled": false, + "isCellVisible": true, + "isDerived": false, + "label": "schema_name", + "computedValue": "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.schema_name))}}" } }, - { - "widgetName": "Table2", - "defaultPageSize": 0, - "columnOrder": [ - "id", - "title", - "due", - "assignee" - ], - "isVisibleDownload": true, - "dynamicPropertyPathList": [], - "displayName": "Table", - "iconSVG": "/static/media/icon.db8a9cbd.svg", - "topRow": 14, - "bottomRow": 38, - "isSortable": true, - "parentRowSpace": 10, - "type": "TABLE_WIDGET", - "defaultSelectedRow": "0", - "hideCard": false, - "animateLoading": true, - "parentColumnSpace": 12.5625, - "dynamicTriggerPathList": [], - "dynamicBindingPathList": [ - { - "key": "tableData" - }, - { - "key": "primaryColumns.due.computedValue" - }, - { - "key": "primaryColumns.assignee.computedValue" - }, - { - "key": "primaryColumns.title.computedValue" - }, - { - "key": "primaryColumns.id.computedValue" - } - ], - "leftColumn": 30, - "primaryColumns": { - "due": { - "index": 0, - "width": 150, - "id": "due", - "horizontalAlignment": "LEFT", - "verticalAlignment": "CENTER", - "columnType": "text", - "textSize": "PARAGRAPH", - "enableFilter": true, - "enableSort": true, - "isVisible": true, - "isDisabled": false, - "isCellVisible": true, - "isDerived": false, - "label": "due", - "computedValue": "{{Table2.sanitizedTableData.map((currentRow) => ( currentRow.due))}}" - }, - "assignee": { - "index": 1, - "width": 150, - "id": "assignee", - "horizontalAlignment": "LEFT", - "verticalAlignment": "CENTER", - "columnType": "text", - "textSize": "PARAGRAPH", - "enableFilter": true, - "enableSort": true, - "isVisible": true, - "isDisabled": false, - "isCellVisible": true, - "isDerived": false, - "label": "assignee", - "computedValue": "{{Table2.sanitizedTableData.map((currentRow) => ( currentRow.assignee))}}" - }, - "title": { - "index": 2, - "width": 150, - "id": "title", - "horizontalAlignment": "LEFT", - "verticalAlignment": "CENTER", - "columnType": "text", - "textSize": "PARAGRAPH", - "enableFilter": true, - "enableSort": true, - "isVisible": true, - "isDisabled": false, - "isCellVisible": true, - "isDerived": false, - "label": "title", - "computedValue": "{{Table2.sanitizedTableData.map((currentRow) => ( currentRow.title))}}" - }, - "id": { - "index": 4, - "width": 150, - "id": "id", - "horizontalAlignment": "LEFT", - "verticalAlignment": "CENTER", - "columnType": "text", - "textSize": "PARAGRAPH", - "enableFilter": true, - "enableSort": true, - "isVisible": true, - "isDisabled": false, - "isCellVisible": true, - "isDerived": false, - "label": "id", - "computedValue": "{{Table2.sanitizedTableData.map((currentRow) => ( currentRow.id))}}" - } + "delimiter": ",", + "key": "5ejs55im17", + "derivedColumns": {}, + "rightColumn": 25, + "textSize": "PARAGRAPH", + "widgetId": "uyyp0qxfdq", + "isVisibleFilters": true, + "tableData": "{{get_schema.data}}", + "isVisible": true, + "label": "Data", + "searchKey": "", + "enableClientSideSearch": true, + "version": 3, + "totalRecordsCount": 0, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "horizontalAlignment": "LEFT", + "isVisibleSearch": true, + "isVisiblePagination": true, + "verticalAlignment": "CENTER", + "columnSizeMap": { + "task": 245, + "step": 62, + "status": 75 + } + }, + { + "widgetName": "Table2", + "defaultPageSize": 0, + "columnOrder": [ + "id", + "title", + "due", + "assignee" + ], + "isVisibleDownload": true, + "dynamicPropertyPathList": [], + "displayName": "Table", + "iconSVG": "/static/media/icon.db8a9cbd.svg", + "topRow": 14, + "bottomRow": 38, + "isSortable": true, + "parentRowSpace": 10, + "type": "TABLE_WIDGET", + "defaultSelectedRow": "0", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 12.5625, + "dynamicTriggerPathList": [], + "dynamicBindingPathList": [ + { + "key": "tableData" }, - "delimiter": ",", - "key": "5ejs55im17", - "derivedColumns": {}, - "rightColumn": 61, - "textSize": "PARAGRAPH", - "widgetId": "r1m4lkt7at", - "isVisibleFilters": true, - "tableData": "{{mockApi.data.headers.info}}", - "isVisible": true, - "label": "Data", - "searchKey": "", - "enableClientSideSearch": true, - "version": 3, - "totalRecordsCount": 0, - "parentId": "0", - "renderMode": "CANVAS", - "isLoading": false, - "horizontalAlignment": "LEFT", - "isVisibleSearch": true, - "isVisiblePagination": true, - "verticalAlignment": "CENTER", - "columnSizeMap": { - "task": 245, - "step": 62, - "status": 75, - "id": 60 + { + "key": "primaryColumns.due.computedValue" + }, + { + "key": "primaryColumns.assignee.computedValue" + }, + { + "key": "primaryColumns.title.computedValue" + }, + { + "key": "primaryColumns.id.computedValue" + } + ], + "leftColumn": 30, + "primaryColumns": { + "due": { + "index": 0, + "width": 150, + "id": "due", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "text", + "textSize": "PARAGRAPH", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isDisabled": false, + "isCellVisible": true, + "isDerived": false, + "label": "due", + "computedValue": "{{Table2.sanitizedTableData.map((currentRow) => ( currentRow.due))}}" + }, + "assignee": { + "index": 1, + "width": 150, + "id": "assignee", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "text", + "textSize": "PARAGRAPH", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isDisabled": false, + "isCellVisible": true, + "isDerived": false, + "label": "assignee", + "computedValue": "{{Table2.sanitizedTableData.map((currentRow) => ( currentRow.assignee))}}" + }, + "title": { + "index": 2, + "width": 150, + "id": "title", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "text", + "textSize": "PARAGRAPH", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isDisabled": false, + "isCellVisible": true, + "isDerived": false, + "label": "title", + "computedValue": "{{Table2.sanitizedTableData.map((currentRow) => ( currentRow.title))}}" + }, + "id": { + "index": 4, + "width": 150, + "id": "id", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "text", + "textSize": "PARAGRAPH", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isDisabled": false, + "isCellVisible": true, + "isDerived": false, + "label": "id", + "computedValue": "{{Table2.sanitizedTableData.map((currentRow) => ( currentRow.id))}}" } }, - { - "widgetName": "Input1", - "displayName": "Input", - "iconSVG": "/static/media/icon.9f505595.svg", - "topRow": 43, - "bottomRow": 47, - "parentRowSpace": 10, - "autoFocus": false, - "type": "INPUT_WIDGET_V2", - "hideCard": false, - "animateLoading": true, - "parentColumnSpace": 12.5625, - "dynamicTriggerPathList": [], - "resetOnSubmit": true, - "leftColumn": 18, - "dynamicBindingPathList": [ - { - "key": "defaultText" - } - ], - "labelStyle": "", - "inputType": "TEXT", - "isDisabled": false, - "key": "t02w4ix9o5", - "isRequired": false, - "rightColumn": 38, - "widgetId": "9timcor5m5", - "isVisible": true, - "label": "", - "allowCurrencyChange": false, - "version": 1, - "parentId": "0", - "renderMode": "CANVAS", - "isLoading": false, - "iconAlign": "left", - "defaultText": "{{JSObject1.myVar1}}" + "delimiter": ",", + "key": "5ejs55im17", + "derivedColumns": {}, + "rightColumn": 61, + "textSize": "PARAGRAPH", + "widgetId": "r1m4lkt7at", + "isVisibleFilters": true, + "tableData": "{{mockApi.data.headers.info}}", + "isVisible": true, + "label": "Data", + "searchKey": "", + "enableClientSideSearch": true, + "version": 3, + "totalRecordsCount": 0, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "horizontalAlignment": "LEFT", + "isVisibleSearch": true, + "isVisiblePagination": true, + "verticalAlignment": "CENTER", + "columnSizeMap": { + "task": 245, + "step": 62, + "status": 75, + "id": 60 } - ] - }, - "layoutOnLoadActions": [ - [ - { - "id": "Page1_get_schema", - "name": "get_schema", - "pluginType": "DB", - "jsonPathKeys": [], - "timeoutInMillisecond": 10000 - } - ], - [ - { - "id": "Page1_mockApi", - "name": "mockApi", - "pluginType": "API", - "jsonPathKeys": [], - "timeoutInMillisecond": 10000 - } - ] + }, + { + "widgetName": "Input1", + "displayName": "Input", + "iconSVG": "/static/media/icon.9f505595.svg", + "topRow": 43, + "bottomRow": 47, + "parentRowSpace": 10, + "autoFocus": false, + "type": "INPUT_WIDGET_V2", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 12.5625, + "dynamicTriggerPathList": [], + "resetOnSubmit": true, + "leftColumn": 18, + "dynamicBindingPathList": [ + { + "key": "defaultText" + } + ], + "labelStyle": "", + "inputType": "TEXT", + "isDisabled": false, + "key": "t02w4ix9o5", + "isRequired": false, + "rightColumn": 38, + "widgetId": "9timcor5m5", + "isVisible": true, + "label": "", + "allowCurrencyChange": false, + "version": 1, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "iconAlign": "left", + "defaultText": "{{JSObject1.myVar1}}" + } + ] + }, + "layoutOnLoadActions": [ + [ + { + "id": "Page1_get_schema", + "name": "get_schema", + "pluginType": "DB", + "jsonPathKeys": [], + "timeoutInMillisecond": 10000 + } ], - "new": false - } - ], - "userPermissions": [] - }, - "publishedPage": { - "name": "Page1", - "slug": "page1", - "layouts": [ - { - "id": "Page1", - "userPermissions": [], - "dsl": { - "widgetName": "MainContainer", - "backgroundColor": "none", - "rightColumn": 1224, - "snapColumns": 16, - "detachFromLayout": true, - "widgetId": "0", - "topRow": 0, - "bottomRow": 1254, - "containerStyle": "none", - "snapRows": 33, - "parentRowSpace": 1, - "type": "CANVAS_WIDGET", - "canExtend": true, - "version": 4, - "minHeight": 1292, - "parentColumnSpace": 1, - "dynamicBindingPathList": [], - "leftColumn": 0, - "children": [] - }, - "new": false - } - ], - "userPermissions": [] - }, - "new": true - } - ], - "publishedDefaultPageName": "Page1", - "unpublishedDefaultPageName": "Page1", - "actionList": [ - { - "id": "Page1_mockApi", - "userPermissions": [ - "read:actions", - "execute:actions", - "manage:actions" - ], - "gitSyncId": "61c580d685c0bd4ccf7d1716_61c580e385c0bd4ccf7d171a", - "pluginType": "API", - "pluginId": "restapi-plugin", - "unpublishedAction": { - "name": "mockApi", - "datasource": { - "userPermissions": [], - "name": "DEFAULT_REST_DATASOURCE", - "pluginId": "restapi-plugin", - "datasourceConfiguration": { - "url": "https://mock-api.appsmith.com" - }, - "invalids": [], - "messages": [], - "isValid": true, - "new": true - }, - "pageId": "Page1", - "actionConfiguration": { - "timeoutInMillisecond": 10000, - "paginationType": "NONE", - "path": "/echo/get", - "headers": [ - { - "key": "info", - "value": "[{\"due\":\"2021-11-23\",\"assignee\":\"Dan.Wyman@hotmail.com\",\"title\":\"Recusan\",\"id\":\"1\"},{\"due\":\"2021-11-23\",\"assignee\":\"Dashawn_Maggio30@gmail.com\",\"title\":\"Dignissimos eaque\",\"id\":\"2\"},{\"due\":\"2021-11-24\",\"assignee\":\"Curt50@gmail.com\",\"title\":\"Voluptas explicabo\",\"id\":\"3\"},{\"due\":\"2021-11-23\",\"assignee\":\"Shanna63@hotmail.com\",\"title\":\"Aut omnis.\",\"id\":\"4\"}]" - } + [ + { + "id": "Page1_mockApi", + "name": "mockApi", + "pluginType": "API", + "jsonPathKeys": [], + "timeoutInMillisecond": 10000 + } + ] ], - "encodeParamsToggle": true, - "queryParameters": [], - "body": "", - "httpMethod": "GET", - "pluginSpecifiedTemplates": [ - { - "value": true - } - ] - }, - "executeOnLoad": true, - "dynamicBindingPathList": [], - "isValid": true, - "invalids": [], - "messages": [], - "jsonPathKeys": [], - "confirmBeforeExecute": false, - "userPermissions": [], - "validName": "mockApi" - }, - "publishedAction": { - "datasource": { - "userPermissions": [], - "messages": [], - "isValid": true, - "new": true - }, - "messages": [], - "confirmBeforeExecute": false, - "userPermissions": [] - }, - "new": false - }, - { - "id": "Page1_get_schema", - "userPermissions": [ - "read:actions", - "execute:actions", - "manage:actions" - ], - "gitSyncId": "61c580d685c0bd4ccf7d1716_61c5832685c0bd4ccf7d171e", - "pluginType": "DB", - "pluginId": "postgres-plugin", - "unpublishedAction": { - "name": "get_schema", - "datasource": { - "id": "mockdata", - "userPermissions": [], - "pluginId": "postgres-plugin", - "messages": [], - "isValid": true, "new": false - }, - "pageId": "Page1", - "actionConfiguration": { - "timeoutInMillisecond": 10000, - "paginationType": "NONE", - "encodeParamsToggle": true, - "body": "SELECT schema_name FROM information_schema.schemata;", - "pluginSpecifiedTemplates": [ - { - "value": true - } - ] - }, - "executeOnLoad": true, - "dynamicBindingPathList": [], - "isValid": true, - "invalids": [], - "messages": [], - "jsonPathKeys": [], - "confirmBeforeExecute": false, - "userPermissions": [], - "validName": "get_schema" - }, - "publishedAction": { - "datasource": { - "userPermissions": [], - "messages": [], - "isValid": true, - "new": true - }, - "messages": [], - "confirmBeforeExecute": false, - "userPermissions": [] - }, - "new": false + } + ], + "userPermissions": [] }, - { - "id": "Page1_myFun1", - "userPermissions": [ - "read:actions", - "execute:actions", - "manage:actions" - ], - "gitSyncId": "61c580d685c0bd4ccf7d1716_61c58ced85c0bd4ccf7d1722", - "pluginType": "JS", - "pluginId": "js-plugin", - "unpublishedAction": { - "name": "myFun1", - "fullyQualifiedName": "JSObject1.myFun1", - "datasource": { + "publishedPage": { + "name": "Page1", + "slug": "page1", + "layouts": [ + { + "id": "Page1", "userPermissions": [], - "name": "UNUSED_DATASOURCE", - "pluginId": "js-plugin", - "messages": [], - "isValid": true, - "new": true - }, - "pageId": "Page1", - "collectionId": "Page1_JSObject1", - "actionConfiguration": { - "timeoutInMillisecond": 10000, - "paginationType": "NONE", - "encodeParamsToggle": true, - "body": "() => {\n\t\t//write code here\n\t\treturn JSObject1.myVar1;\n\t}", - "jsArguments": [], - "isAsync": false - }, - "executeOnLoad": false, - "dynamicBindingPathList": [ - { - "key": "body" - } - ], - "isValid": true, - "invalids": [], - "messages": [], - "jsonPathKeys": [ - "() => {\n\t\t//write code here\n\t\treturn JSObject1.myVar1;\n\t}" - ], - "confirmBeforeExecute": false, - "userPermissions": [], - "validName": "JSObject1.myFun1" - }, - "publishedAction": { - "datasource": { - "userPermissions": [], - "messages": [], - "isValid": true, - "new": true - }, - "messages": [], - "confirmBeforeExecute": false, - "userPermissions": [] - }, - "new": false - }, - { - "id": "Page1_myFun2", - "userPermissions": [ - "read:actions", - "execute:actions", - "manage:actions" - ], - "gitSyncId": "61c580d685c0bd4ccf7d1716_61c58ced85c0bd4ccf7d1724", - "pluginType": "JS", - "pluginId": "js-plugin", - "unpublishedAction": { - "name": "myFun2", - "fullyQualifiedName": "JSObject1.myFun2", - "datasource": { - "userPermissions": [], - "name": "UNUSED_DATASOURCE", - "pluginId": "js-plugin", - "messages": [], - "isValid": true, - "new": true - }, - "pageId": "Page1", - "collectionId": "Page1_JSObject1", - "actionConfiguration": { - "timeoutInMillisecond": 10000, - "paginationType": "NONE", - "encodeParamsToggle": true, - "body": "() => {\n\t\t//write code here\n\t}", - "jsArguments": [], - "isAsync": false - }, - "executeOnLoad": false, - "dynamicBindingPathList": [ - { - "key": "body" - } - ], - "isValid": true, - "invalids": [], - "messages": [], - "jsonPathKeys": [ - "() => {\n\t\t//write code here\n\t}" - ], - "confirmBeforeExecute": false, - "userPermissions": [], - "validName": "JSObject1.myFun2" - }, - "publishedAction": { - "datasource": { - "userPermissions": [], - "messages": [], - "isValid": true, - "new": true - }, - "messages": [], - "confirmBeforeExecute": false, - "userPermissions": [] - }, - "new": false - } - ], - "actionCollectionList": [ - { - "id": "Page1_JSObject1", - "userPermissions": [ - "read:actions", - "execute:actions", - "manage:actions" - ], - "gitSyncId": "61c580d685c0bd4ccf7d1716_61c58ced85c0bd4ccf7d1726", - "unpublishedCollection": { - "name": "JSObject1", - "pageId": "Page1", - "pluginId": "js-plugin", - "pluginType": "JS", - "actionIds": [], - "archivedActionIds": [], - "actions": [], - "archivedActions": [], - "body": "export default {\n\tmyVar1: \"Submit\",\n\tmyVar2: {},\n\tmyFun1: () => {\n\t\t//write code here\n\t\treturn this.myVar1;\n\t},\n\tmyFun2: () => {\n\t\t//write code here\n\t}\n}", - "variables": [ - { - "name": "myVar1", - "value": "Submit" + "dsl": { + "widgetName": "MainContainer", + "backgroundColor": "none", + "rightColumn": 1224, + "snapColumns": 16, + "detachFromLayout": true, + "widgetId": "0", + "topRow": 0, + "bottomRow": 1254, + "containerStyle": "none", + "snapRows": 33, + "parentRowSpace": 1, + "type": "CANVAS_WIDGET", + "canExtend": true, + "version": 4, + "minHeight": 1292, + "parentColumnSpace": 1, + "dynamicBindingPathList": [], + "leftColumn": 0, + "children": [] }, + "new": false + } + ], + "userPermissions": [] + }, + "new": true + } + ], + "publishedDefaultPageName": "Page1", + "unpublishedDefaultPageName": "Page1", + "actionList": [ + { + "id": "Page1_mockApi", + "userPermissions": [ + "read:actions", + "execute:actions", + "manage:actions" + ], + "gitSyncId": "61c580d685c0bd4ccf7d1716_61c580e385c0bd4ccf7d171a", + "pluginType": "API", + "pluginId": "restapi-plugin", + "unpublishedAction": { + "name": "mockApi", + "datasource": { + "userPermissions": [], + "name": "DEFAULT_REST_DATASOURCE", + "pluginId": "restapi-plugin", + "datasourceConfiguration": { + "url": "https://mock-api.appsmith.com" + }, + "invalids": [], + "messages": [], + "isValid": true, + "new": true + }, + "pageId": "Page1", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "path": "/echo/get", + "headers": [ { - "name": "myVar2", - "value": {} + "key": "info", + "value": "[{\"due\":\"2021-11-23\",\"assignee\":\"Dan.Wyman@hotmail.com\",\"title\":\"Recusan\",\"id\":\"1\"},{\"due\":\"2021-11-23\",\"assignee\":\"Dashawn_Maggio30@gmail.com\",\"title\":\"Dignissimos eaque\",\"id\":\"2\"},{\"due\":\"2021-11-24\",\"assignee\":\"Curt50@gmail.com\",\"title\":\"Voluptas explicabo\",\"id\":\"3\"},{\"due\":\"2021-11-23\",\"assignee\":\"Shanna63@hotmail.com\",\"title\":\"Aut omnis.\",\"id\":\"4\"}]" + } + ], + "encodeParamsToggle": true, + "queryParameters": [], + "body": "", + "httpMethod": "GET", + "pluginSpecifiedTemplates": [ + { + "value": true } ] }, - "new": false + "executeOnLoad": true, + "dynamicBindingPathList": [], + "isValid": true, + "invalids": [], + "messages": [], + "jsonPathKeys": [], + "confirmBeforeExecute": false, + "userPermissions": [], + "validName": "mockApi" + }, + "publishedAction": { + "datasource": { + "userPermissions": [], + "messages": [], + "isValid": true, + "new": true + }, + "messages": [], + "confirmBeforeExecute": false, + "userPermissions": [] + }, + "new": false + }, + { + "id": "Page1_get_schema", + "userPermissions": [ + "read:actions", + "execute:actions", + "manage:actions" + ], + "gitSyncId": "61c580d685c0bd4ccf7d1716_61c5832685c0bd4ccf7d171e", + "pluginType": "DB", + "pluginId": "postgres-plugin", + "unpublishedAction": { + "name": "get_schema", + "datasource": { + "id": "mockdata", + "userPermissions": [], + "pluginId": "postgres-plugin", + "messages": [], + "isValid": true, + "new": false + }, + "pageId": "Page1", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "encodeParamsToggle": true, + "body": "SELECT schema_name FROM information_schema.schemata;", + "pluginSpecifiedTemplates": [ + { + "value": true + } + ] + }, + "executeOnLoad": true, + "dynamicBindingPathList": [], + "isValid": true, + "invalids": [], + "messages": [], + "jsonPathKeys": [], + "confirmBeforeExecute": false, + "userPermissions": [], + "validName": "get_schema" + }, + "publishedAction": { + "datasource": { + "userPermissions": [], + "messages": [], + "isValid": true, + "new": true + }, + "messages": [], + "confirmBeforeExecute": false, + "userPermissions": [] + }, + "new": false + }, + { + "id": "Page1_myFun1", + "userPermissions": [ + "read:actions", + "execute:actions", + "manage:actions" + ], + "gitSyncId": "61c580d685c0bd4ccf7d1716_61c58ced85c0bd4ccf7d1722", + "pluginType": "JS", + "pluginId": "js-plugin", + "unpublishedAction": { + "name": "myFun1", + "fullyQualifiedName": "JSObject1.myFun1", + "datasource": { + "userPermissions": [], + "name": "UNUSED_DATASOURCE", + "pluginId": "js-plugin", + "messages": [], + "isValid": true, + "new": true + }, + "pageId": "Page1", + "collectionId": "Page1_JSObject1", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "encodeParamsToggle": true, + "body": "() => {\n\t\t//write code here\n\t\treturn JSObject1.myVar1;\n\t}", + "jsArguments": [], + "isAsync": false + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { + "key": "body" + } + ], + "isValid": true, + "invalids": [], + "messages": [], + "jsonPathKeys": [ + "() => {\n\t\t//write code here\n\t\treturn JSObject1.myVar1;\n\t}" + ], + "confirmBeforeExecute": false, + "userPermissions": [], + "validName": "JSObject1.myFun1" + }, + "publishedAction": { + "datasource": { + "userPermissions": [], + "messages": [], + "isValid": true, + "new": true + }, + "messages": [], + "confirmBeforeExecute": false, + "userPermissions": [] + }, + "new": false + }, + { + "id": "Page1_myFun2", + "userPermissions": [ + "read:actions", + "execute:actions", + "manage:actions" + ], + "gitSyncId": "61c580d685c0bd4ccf7d1716_61c58ced85c0bd4ccf7d1724", + "pluginType": "JS", + "pluginId": "js-plugin", + "unpublishedAction": { + "name": "myFun2", + "fullyQualifiedName": "JSObject1.myFun2", + "datasource": { + "userPermissions": [], + "name": "UNUSED_DATASOURCE", + "pluginId": "js-plugin", + "messages": [], + "isValid": true, + "new": true + }, + "pageId": "Page1", + "collectionId": "Page1_JSObject1", + "actionConfiguration": { + "timeoutInMillisecond": 10000, + "paginationType": "NONE", + "encodeParamsToggle": true, + "body": "() => {\n\t\t//write code here\n\t}", + "jsArguments": [], + "isAsync": false + }, + "executeOnLoad": false, + "dynamicBindingPathList": [ + { + "key": "body" + } + ], + "isValid": true, + "invalids": [], + "messages": [], + "jsonPathKeys": [ + "() => {\n\t\t//write code here\n\t}" + ], + "confirmBeforeExecute": false, + "userPermissions": [], + "validName": "JSObject1.myFun2" + }, + "publishedAction": { + "datasource": { + "userPermissions": [], + "messages": [], + "isValid": true, + "new": true + }, + "messages": [], + "confirmBeforeExecute": false, + "userPermissions": [] + }, + "new": false + } + ], + "actionCollectionList": [ + { + "id": "Page1_JSObject1", + "userPermissions": [ + "read:actions", + "execute:actions", + "manage:actions" + ], + "gitSyncId": "61c580d685c0bd4ccf7d1716_61c58ced85c0bd4ccf7d1726", + "unpublishedCollection": { + "name": "JSObject1", + "pageId": "Page1", + "pluginId": "js-plugin", + "pluginType": "JS", + "actionIds": [], + "archivedActionIds": [], + "actions": [], + "archivedActions": [], + "body": "export default {\n\tmyVar1: \"Submit\",\n\tmyVar2: {},\n\tmyFun1: () => {\n\t\t//write code here\n\t\treturn this.myVar1;\n\t},\n\tmyFun2: () => {\n\t\t//write code here\n\t}\n}", + "variables": [ + { + "name": "myVar1", + "value": "Submit" + }, + { + "name": "myVar2", + "value": {} + } + ] + }, + "new": false + } + ], + "decryptedFields": { + "mockdata": { + "password": "docker", + "authType": "com.appsmith.external.models.DBAuth", + "dbAuth": { + "authenticationType": "dbAuth", + "username": "docker", + "databaseName": "fakeapi" } - ], - "decryptedFields": { - "mockdata": { - "password": "docker", - "authType": "com.appsmith.external.models.DBAuth", - "dbAuth": { - "authenticationType": "dbAuth", - "username": "docker", - "databaseName": "fakeapi" - } - } - }, - "editModeTheme": { - "name": "Classic", - "new": true, - "isSystemTheme": true - }, - "publishedTheme": { - "name": "Classic", - "new": true, - "isSystemTheme": true - }, - "publishedLayoutmongoEscapedWidgets": {}, - "unpublishedLayoutmongoEscapedWidgets": {} - } + } + }, + "editModeTheme": { + "name": "Classic", + "new": true, + "isSystemTheme": true + }, + "publishedTheme": { + "name": "Classic", + "new": true, + "isSystemTheme": true + }, + "publishedLayoutmongoEscapedWidgets": {}, + "unpublishedLayoutmongoEscapedWidgets": {} +} \ No newline at end of file diff --git a/app/client/cypress/fixtures/jsonFormDslWithSchema.json b/app/client/cypress/fixtures/jsonFormDslWithSchema.json new file mode 100644 index 0000000000..1c874074a6 --- /dev/null +++ b/app/client/cypress/fixtures/jsonFormDslWithSchema.json @@ -0,0 +1,393 @@ +{ + "dsl": { + "widgetName": "MainContainer", + "backgroundColor": "none", + "rightColumn": 1168, + "snapColumns": 64, + "detachFromLayout": true, + "widgetId": "0", + "topRow": 0, + "bottomRow": 680, + "containerStyle": "none", + "snapRows": 125, + "parentRowSpace": 1, + "type": "CANVAS_WIDGET", + "canExtend": true, + "version": 47, + "minHeight": 870, + "parentColumnSpace": 1, + "dynamicTriggerPathList": [], + "dynamicBindingPathList": [], + "leftColumn": 0, + "children": [ + { + "widgetName": "Text1", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 54, + "bottomRow": 58, + "parentRowSpace": 10, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 18.0625, + "leftColumn": 22, + "text": "Label", + "key": "zgsygilz5a", + "rightColumn": 38, + "textAlign": "LEFT", + "widgetId": "ums2hvawa0", + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "version": 1, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "PARAGRAPH" + }, + { + "schema": { + "__root_schema__": { + "children": { + "name": { + "children": {}, + "dataType": "string", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.name))(JSONForm1.sourceData, JSONForm1.formData, JSONForm1.fieldState)}}", + "fieldType": "Text Input", + "sourceData": "John", + "isCustomField": false, + "accessor": "name", + "identifier": "name", + "position": 0, + "originalIdentifier": "name", + "isDisabled": false, + "isRequired": false, + "isSpellCheck": false, + "isVisible": true, + "label": "Name" + }, + "age": { + "children": {}, + "dataType": "number", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.age))(JSONForm1.sourceData, JSONForm1.formData, JSONForm1.fieldState)}}", + "fieldType": "Number Input", + "sourceData": 30, + "isCustomField": false, + "accessor": "age", + "identifier": "age", + "position": 1, + "originalIdentifier": "age", + "isDisabled": false, + "isRequired": false, + "isSpellCheck": false, + "isVisible": true, + "label": "Age" + }, + "dob": { + "children": {}, + "dataType": "string", + "defaultValue": "{{((sourceData, formData, fieldState) => (moment(sourceData.dob, \"MM/DD/YYYY\").format(\"YYYY-MM-DDTHH:mm:ss.sssZ\")))(JSONForm1.sourceData, JSONForm1.formData, JSONForm1.fieldState)}}", + "fieldType": "Datepicker", + "sourceData": "10/12/1992", + "isCustomField": false, + "accessor": "dob", + "identifier": "dob", + "position": 2, + "originalIdentifier": "dob", + "closeOnSelection": false, + "dateFormat": "MM/DD/YYYY", + "isDisabled": false, + "isRequired": false, + "label": "Dob", + "maxDate": "2121-12-31T18:29:00.000Z", + "minDate": "1920-12-31T18:30:00.000Z", + "convertToISO": false, + "shortcuts": false, + "isVisible": true + }, + "migrant": { + "children": {}, + "dataType": "boolean", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.migrant))(JSONForm1.sourceData, JSONForm1.formData, JSONForm1.fieldState)}}", + "fieldType": "Switch", + "sourceData": false, + "isCustomField": false, + "accessor": "migrant", + "identifier": "migrant", + "position": 3, + "originalIdentifier": "migrant", + "alignWidget": "LEFT", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "label": "Migrant" + }, + "address": { + "children": { + "street": { + "children": {}, + "dataType": "string", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.address.street))(JSONForm1.sourceData, JSONForm1.formData, JSONForm1.fieldState)}}", + "fieldType": "Text Input", + "sourceData": "Koramangala", + "isCustomField": false, + "accessor": "street", + "identifier": "street", + "position": 0, + "originalIdentifier": "street", + "isDisabled": false, + "isRequired": false, + "isSpellCheck": false, + "isVisible": true, + "label": "Street" + }, + "city": { + "children": {}, + "dataType": "string", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.address.city))(JSONForm1.sourceData, JSONForm1.formData, JSONForm1.fieldState)}}", + "fieldType": "Text Input", + "sourceData": "Bangalore", + "isCustomField": false, + "accessor": "city", + "identifier": "city", + "position": 1, + "originalIdentifier": "city", + "isDisabled": false, + "isRequired": false, + "isSpellCheck": false, + "isVisible": true, + "label": "City" + } + }, + "dataType": "object", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.address))(JSONForm1.sourceData, JSONForm1.formData, JSONForm1.fieldState)}}", + "fieldType": "Object", + "sourceData": { + "street": "Koramangala", + "city": "Bangalore" + }, + "isCustomField": false, + "accessor": "address", + "identifier": "address", + "position": 4, + "originalIdentifier": "address", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "label": "Address" + }, + "education": { + "children": { + "__array_item__": { + "children": { + "college": { + "children": {}, + "dataType": "string", + "fieldType": "Text Input", + "sourceData": "MIT", + "isCustomField": false, + "accessor": "college", + "identifier": "college", + "position": 0, + "originalIdentifier": "college", + "isDisabled": false, + "isRequired": false, + "isSpellCheck": false, + "isVisible": true, + "label": "College" + }, + "year": { + "children": {}, + "dataType": "string", + "fieldType": "Datepicker", + "sourceData": "20/10/2014", + "isCustomField": false, + "accessor": "year", + "identifier": "year", + "position": 1, + "originalIdentifier": "year", + "closeOnSelection": false, + "dateFormat": "DD/MM/YYYY", + "isDisabled": false, + "isRequired": false, + "label": "Year", + "convertToISO": false, + "maxDate": "2121-12-31T18:29:00.000Z", + "minDate": "1920-12-31T18:30:00.000Z", + "shortcuts": false, + "isVisible": true + } + }, + "dataType": "object", + "fieldType": "Object", + "sourceData": { + "college": "MIT", + "year": "20/10/2014" + }, + "isCustomField": false, + "accessor": "__array_item__", + "identifier": "__array_item__", + "position": -1, + "originalIdentifier": "__array_item__", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "label": "Array Item" + } + }, + "dataType": "array", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.education))(JSONForm1.sourceData, JSONForm1.formData, JSONForm1.fieldState)}}", + "fieldType": "Array", + "sourceData": [ + { + "college": "MIT", + "year": "20/10/2014" + } + ], + "isCustomField": false, + "accessor": "education", + "identifier": "education", + "position": 5, + "originalIdentifier": "education", + "backgroundColor": "#FAFAFA", + "isCollapsible": true, + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "label": "Education" + }, + "hobbies": { + "children": {}, + "dataType": "array", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.hobbies))(JSONForm1.sourceData, JSONForm1.formData, JSONForm1.fieldState)}}", + "fieldType": "Multiselect", + "sourceData": [ + "travelling", + "swimming" + ], + "isCustomField": false, + "accessor": "hobbies", + "identifier": "hobbies", + "position": 6, + "originalIdentifier": "hobbies", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "label": "Hobbies", + "serverSideFiltering": false, + "options": [ + { + "label": "Blue", + "value": "BLUE" + }, + { + "label": "Green", + "value": "GREEN" + }, + { + "label": "Red", + "value": "RED" + } + ] + } + }, + "dataType": "object", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData))(JSONForm1.sourceData, JSONForm1.formData, JSONForm1.fieldState)}}", + "fieldType": "Object", + "sourceData": { + "name": "John", + "age": 30, + "dob": "10/12/1992", + "migrant": false, + "address": { + "street": "Koramangala", + "city": "Bangalore" + }, + "education": [ + { + "college": "MIT", + "year": "20/10/2014" + } + ], + "hobbies": [ + "travelling", + "swimming" + ] + }, + "isCustomField": false, + "name": "", + "identifier": "", + "position": -1, + "originalIdentifier": "", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "label": "" + } + }, + "widgetName": "JSONForm1", + "displayName": "JSON Form", + "iconSVG": "/static/media/icon.6bacf7df.svg", + "topRow": 5, + "bottomRow": 45, + "parentRowSpace": 10, + "title": "Form", + "type": "JSON_FORM_WIDGET", + "hideCard": false, + "parentColumnSpace": 18.0625, + "dynamicTriggerPathList": [], + "autoGenerateForm": true, + "leftColumn": 18, + "dynamicBindingPathList": [ + { + "key": "schema.__root_schema__.children.name.defaultValue" + }, + { + "key": "schema.__root_schema__.children.age.defaultValue" + }, + { + "key": "schema.__root_schema__.children.dob.defaultValue" + }, + { + "key": "schema.__root_schema__.children.migrant.defaultValue" + }, + { + "key": "schema.__root_schema__.children.address.children.street.defaultValue" + }, + { + "key": "schema.__root_schema__.children.address.children.city.defaultValue" + }, + { + "key": "schema.__root_schema__.children.address.defaultValue" + }, + { + "key": "schema.__root_schema__.children.education.defaultValue" + }, + { + "key": "schema.__root_schema__.children.hobbies.defaultValue" + }, + { + "key": "schema.__root_schema__.defaultValue" + } + ], + "sourceData": "{\n \"name\": \"John\",\n \"age\": 30,\n \"dob\": \"10/12/1992\",\n \"migrant\": false,\n \"address\": {\n \"street\": \"Koramangala\",\n \"city\": \"Bangalore\"\n },\n \"education\": [\n {\n \"college\": \"MIT\",\n \"year\": \"20/10/2014\"\n }\n ],\n \"hobbies\": [\"travelling\", \"swimming\"]\n}", + "showReset": true, + "key": "4x3ilx80d3", + "backgroundColor": "#fff", + "rightColumn": 43, + "widgetId": "u77r23ogdl", + "isVisible": true, + "version": 1, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "scrollContents": true, + "fixedFooter": true, + "disabledWhenInvalid": true, + "submitButtonLabel": "Submit", + "resetButtonLabel": "Reset" + } + ] +} +} \ No newline at end of file diff --git a/app/client/cypress/fixtures/jsonFormDslWithSchemaAndWithoutSourceData.json b/app/client/cypress/fixtures/jsonFormDslWithSchemaAndWithoutSourceData.json new file mode 100644 index 0000000000..382a1b1316 --- /dev/null +++ b/app/client/cypress/fixtures/jsonFormDslWithSchemaAndWithoutSourceData.json @@ -0,0 +1,377 @@ +{ + "dsl": { + "widgetName": "MainContainer", + "backgroundColor": "none", + "rightColumn": 1168, + "snapColumns": 64, + "detachFromLayout": true, + "widgetId": "0", + "topRow": 0, + "bottomRow": 680, + "containerStyle": "none", + "snapRows": 125, + "parentRowSpace": 1, + "type": "CANVAS_WIDGET", + "canExtend": true, + "version": 47, + "minHeight": 870, + "parentColumnSpace": 1, + "dynamicTriggerPathList": [], + "dynamicBindingPathList": [], + "leftColumn": 0, + "children": [ + { + "widgetName": "Text1", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 54, + "bottomRow": 58, + "parentRowSpace": 10, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 18.0625, + "leftColumn": 22, + "text": "Label", + "key": "zgsygilz5a", + "rightColumn": 38, + "textAlign": "LEFT", + "widgetId": "ums2hvawa0", + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "version": 1, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "PARAGRAPH" + }, + { + "isVisible": true, + "animateLoading": true, + "backgroundColor": "#fff", + "disabledWhenInvalid": true, + "fixedFooter": true, + "autoGenerateForm": true, + "schema": { + "__root_schema__": { + "children": { + "name": { + "children": {}, + "dataType": "string", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.name))(JSONForm1.sourceData, JSONForm1.formData, JSONForm1.fieldState)}}", + "fieldType": "Text Input", + "sourceData": "John", + "isCustomField": false, + "accessor": "name", + "identifier": "name", + "position": 0, + "originalIdentifier": "name", + "iconAlign": "left", + "isDisabled": false, + "isRequired": false, + "isSpellCheck": false, + "isVisible": true, + "label": "Name" + }, + "age": { + "children": {}, + "dataType": "number", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.age))(JSONForm1.sourceData, JSONForm1.formData, JSONForm1.fieldState)}}", + "fieldType": "Number Input", + "sourceData": 30, + "isCustomField": false, + "accessor": "age", + "identifier": "age", + "position": 1, + "originalIdentifier": "age", + "iconAlign": "left", + "isDisabled": false, + "isRequired": false, + "isSpellCheck": false, + "isVisible": true, + "label": "Age" + }, + "dob": { + "children": {}, + "dataType": "string", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.dob))(JSONForm1.sourceData, JSONForm1.formData, JSONForm1.fieldState)}}", + "fieldType": "Datepicker", + "sourceData": "10/12/1992", + "isCustomField": false, + "accessor": "dob", + "identifier": "dob", + "position": 2, + "originalIdentifier": "dob", + "closeOnSelection": false, + "convertToISO": false, + "dateFormat": "MM/DD/YYYY", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "label": "Dob", + "maxDate": "2121-12-31T18:29:00.000Z", + "minDate": "1920-12-31T18:30:00.000Z", + "shortcuts": false, + "timePrecision": "minute" + }, + "migrant": { + "children": {}, + "dataType": "boolean", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.migrant))(JSONForm1.sourceData, JSONForm1.formData, JSONForm1.fieldState)}}", + "fieldType": "Switch", + "sourceData": false, + "isCustomField": false, + "accessor": "migrant", + "identifier": "migrant", + "position": 3, + "originalIdentifier": "migrant", + "alignWidget": "LEFT", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "label": "Migrant" + }, + "address": { + "children": { + "street": { + "children": {}, + "dataType": "string", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.address.street))(JSONForm1.sourceData, JSONForm1.formData, JSONForm1.fieldState)}}", + "fieldType": "Text Input", + "sourceData": "Koramangala", + "isCustomField": false, + "accessor": "street", + "identifier": "street", + "position": 0, + "originalIdentifier": "street", + "iconAlign": "left", + "isDisabled": false, + "isRequired": false, + "isSpellCheck": false, + "isVisible": true, + "label": "Street" + }, + "city": { + "children": {}, + "dataType": "string", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.address.city))(JSONForm1.sourceData, JSONForm1.formData, JSONForm1.fieldState)}}", + "fieldType": "Text Input", + "sourceData": "Bangalore", + "isCustomField": false, + "accessor": "city", + "identifier": "city", + "position": 1, + "originalIdentifier": "city", + "iconAlign": "left", + "isDisabled": false, + "isRequired": false, + "isSpellCheck": false, + "isVisible": true, + "label": "City" + } + }, + "dataType": "object", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.address))(JSONForm1.sourceData, JSONForm1.formData, JSONForm1.fieldState)}}", + "fieldType": "Object", + "sourceData": { + "street": "Koramangala", + "city": "Bangalore" + }, + "isCustomField": false, + "accessor": "address", + "identifier": "address", + "position": 4, + "originalIdentifier": "address", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "label": "Address" + }, + "education": { + "children": { + "__array_item__": { + "children": { + "college": { + "children": {}, + "dataType": "string", + "fieldType": "Text Input", + "sourceData": "MIT", + "isCustomField": false, + "accessor": "college", + "identifier": "college", + "position": 0, + "originalIdentifier": "college", + "iconAlign": "left", + "isDisabled": false, + "isRequired": false, + "isSpellCheck": false, + "isVisible": true, + "label": "College" + }, + "year": { + "children": {}, + "dataType": "string", + "fieldType": "Datepicker", + "sourceData": "20/10/2014", + "isCustomField": false, + "accessor": "year", + "identifier": "year", + "position": 1, + "originalIdentifier": "year", + "closeOnSelection": false, + "convertToISO": false, + "dateFormat": "DD/MM/YYYY", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "label": "Year", + "maxDate": "2121-12-31T18:29:00.000Z", + "minDate": "1920-12-31T18:30:00.000Z", + "shortcuts": false, + "timePrecision": "minute" + } + }, + "dataType": "object", + "fieldType": "Object", + "sourceData": { + "college": "MIT", + "year": "20/10/2014" + }, + "isCustomField": false, + "accessor": "__array_item__", + "identifier": "__array_item__", + "position": -1, + "originalIdentifier": "__array_item__", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "label": "Array Item" + } + }, + "dataType": "array", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData.education))(JSONForm1.sourceData, JSONForm1.formData, JSONForm1.fieldState)}}", + "fieldType": "Array", + "sourceData": [ + { + "college": "MIT", + "year": "20/10/2014" + } + ], + "isCustomField": false, + "accessor": "education", + "identifier": "education", + "position": 5, + "originalIdentifier": "education", + "backgroundColor": "#FAFAFA", + "isCollapsible": true, + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "label": "Education" + } + }, + "dataType": "object", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData))(JSONForm1.sourceData, JSONForm1.formData, JSONForm1.fieldState)}}", + "fieldType": "Object", + "sourceData": { + "name": "John", + "age": 30, + "dob": "10/12/1992", + "migrant": false, + "address": { + "street": "Koramangala", + "city": "Bangalore" + }, + "education": [ + { + "college": "MIT", + "year": "20/10/2014" + } + ] + }, + "isCustomField": false, + "name": "__root_schema__", + "accessor": "__root_schema__", + "identifier": "__root_schema__", + "position": -1, + "originalIdentifier": "__root_schema__", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "label": "" + } + }, + "scrollContents": true, + "showReset": true, + "title": "Form", + "version": 1, + "widgetName": "JSONForm1", + "submitButtonStyles": { + "buttonColor": "#03B365", + "buttonVariant": "PRIMARY" + }, + "resetButtonStyles": { + "buttonColor": "#03B365", + "buttonVariant": "SECONDARY" + }, + "sourceData": "", + "type": "JSON_FORM_WIDGET", + "hideCard": false, + "displayName": "JSON Form", + "key": "sh61xsjzqi", + "iconSVG": "/static/media/icon.6bacf7df.svg", + "widgetId": "ie1fkmka46", + "renderMode": "CANVAS", + "isLoading": false, + "parentColumnSpace": 42.5625, + "parentRowSpace": 10, + "leftColumn": 29, + "rightColumn": 54, + "topRow": 29, + "bottomRow": 79, + "parentId": "0", + "submitButtonLabel": "Submit", + "resetButtonLabel": "Reset", + "dynamicPropertyPathList": [ + { + "key": "schema.__root_schema__.children.dob.defaultValue" + }, + { + "key": "schema.__root_schema__.children.migrant.defaultValue" + } + ], + "dynamicBindingPathList": [ + { + "key": "schema.__root_schema__.children.name.defaultValue" + }, + { + "key": "schema.__root_schema__.defaultValue" + }, + { + "key": "schema.__root_schema__.children.age.defaultValue" + }, + { + "key": "schema.__root_schema__.children.dob.defaultValue" + }, + { + "key": "schema.__root_schema__.children.migrant.defaultValue" + }, + { + "key": "schema.__root_schema__.children.address.children.street.defaultValue" + }, + { + "key": "schema.__root_schema__.children.address.children.city.defaultValue" + }, + { + "key": "schema.__root_schema__.children.address.defaultValue" + }, + { + "key": "schema.__root_schema__.children.education.defaultValue" + } + ], + "dynamicTriggerPathList": [] + } + ] + } +} \ No newline at end of file diff --git a/app/client/cypress/fixtures/jsonFormDslWithoutSchema.json b/app/client/cypress/fixtures/jsonFormDslWithoutSchema.json new file mode 100644 index 0000000000..71edcb5d5b --- /dev/null +++ b/app/client/cypress/fixtures/jsonFormDslWithoutSchema.json @@ -0,0 +1,55 @@ +{ + "dsl": { + "widgetName": "MainContainer", + "backgroundColor": "none", + "rightColumn": 1168, + "snapColumns": 64, + "detachFromLayout": true, + "widgetId": "0", + "topRow": 0, + "bottomRow": 610, + "containerStyle": "none", + "snapRows": 125, + "parentRowSpace": 1, + "type": "CANVAS_WIDGET", + "canExtend": true, + "version": 47, + "minHeight": 520, + "parentColumnSpace": 1, + "dynamicTriggerPathList": [], + "dynamicBindingPathList": [], + "leftColumn": 0, + "children": [ + { + "isVisible": true, + "backgroundColor": "#fff", + "disabledWhenInvalid": true, + "fixedFooter": true, + "schema": {}, + "scrollContents": true, + "showReset": true, + "title": "Form", + "version": 1, + "widgetName": "JSONForm1", + "type": "JSON_FORM_WIDGET", + "autoGenerateForm": true, + "hideCard": false, + "displayName": "JSON Form", + "key": "cak4mvjrvr", + "iconSVG": "/static/media/icon.6bacf7df.svg", + "widgetId": "1gnss27afd", + "renderMode": "CANVAS", + "isLoading": false, + "parentColumnSpace": 18.0625, + "parentRowSpace": 10, + "leftColumn": 21, + "rightColumn": 46, + "topRow": 7, + "bottomRow": 47, + "parentId": "0", + "submitButtonLabel": "Submit", + "resetButtonLabel": "Reset" + } + ] + } +} \ No newline at end of file diff --git a/app/client/cypress/fixtures/jsonFormUnicodeDSLWithoutSourceData.json b/app/client/cypress/fixtures/jsonFormUnicodeDSLWithoutSourceData.json new file mode 100644 index 0000000000..fa1dffd3b2 --- /dev/null +++ b/app/client/cypress/fixtures/jsonFormUnicodeDSLWithoutSourceData.json @@ -0,0 +1,265 @@ +{ + "dsl": { + "widgetName": "MainContainer", + "backgroundColor": "none", + "rightColumn": 1168, + "snapColumns": 64, + "detachFromLayout": true, + "widgetId": "0", + "topRow": 0, + "bottomRow": 1340, + "containerStyle": "none", + "snapRows": 125, + "parentRowSpace": 1, + "type": "CANVAS_WIDGET", + "canExtend": true, + "version": 52, + "minHeight": 1320, + "parentColumnSpace": 1, + "dynamicBindingPathList": [], + "leftColumn": 0, + "children": [ + { + "widgetName": "Text1", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 0, + "bottomRow": 58, + "parentRowSpace": 10, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 26.890625, + "dynamicTriggerPathList": [], + "leftColumn": 0, + "dynamicBindingPathList": [ + { + "key": "text" + } + ], + "shouldTruncate": false, + "truncateButtonColor": "#FFC13D", + "text": "{{JSONForm1.formData}}", + "key": "fcglufpc9q", + "rightColumn": 20, + "textAlign": "LEFT", + "widgetId": "2cvwkaegxy", + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "shouldScroll": false, + "version": 1, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "PARAGRAPH" + }, + { + "schema": { + "__root_schema__": { + "children": { + "xn__80a1afdk69b": { + "children": { + "xn__mgbuhw": { + "children": {}, + "dataType": "string", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData[\"суроға\"][\"شارع\"]))(JSONForm1.sourceData, JSONForm1.formData, JSONForm1.fieldState)}}", + "fieldType": "Text Input", + "sourceData": "Koramangala", + "isCustomField": false, + "accessor": "شارع", + "identifier": "xn__mgbuhw", + "position": 0, + "originalIdentifier": "شارع", + "iconAlign": "left", + "isDisabled": false, + "isRequired": false, + "isSpellCheck": false, + "isVisible": true, + "label": "شارع" + } + }, + "dataType": "object", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData[\"суроға\"]))(JSONForm1.sourceData, JSONForm1.formData, JSONForm1.fieldState)}}", + "fieldType": "Object", + "sourceData": { + "شارع": "Koramangala" + }, + "isCustomField": false, + "accessor": "суроға", + "identifier": "xn__80a1afdk69b", + "position": 0, + "originalIdentifier": "суроға", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "label": "Суроға" + }, + "xn__12ca5huag4ce3a": { + "children": { + "__array_item__": { + "children": { + "xn__ohco9d4d": { + "children": {}, + "dataType": "string", + "fieldType": "Text Input", + "sourceData": "MIT", + "isCustomField": false, + "accessor": "କଲେଜ", + "identifier": "xn__ohco9d4d", + "position": 0, + "originalIdentifier": "କଲେଜ", + "iconAlign": "left", + "isDisabled": false, + "isRequired": false, + "isSpellCheck": false, + "isVisible": true, + "label": "କଲେଜ" + } + }, + "dataType": "object", + "fieldType": "Object", + "sourceData": { + "କଲେଜ": "MIT" + }, + "isCustomField": false, + "accessor": "__array_item__", + "identifier": "__array_item__", + "position": -1, + "originalIdentifier": "__array_item__", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "label": "Array Item" + } + }, + "dataType": "array", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData[\"การศึกษา\"]))(JSONForm1.sourceData, JSONForm1.formData, JSONForm1.fieldState)}}", + "fieldType": "Array", + "sourceData": [ + { + "କଲେଜ": "MIT" + } + ], + "isCustomField": false, + "accessor": "การศึกษา", + "identifier": "xn__12ca5huag4ce3a", + "position": 1, + "originalIdentifier": "การศึกษา", + "backgroundColor": "#FAFAFA", + "isCollapsible": true, + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "label": "การศึกษา" + }, + "xn__l2bm1c": { + "children": {}, + "dataType": "string", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData[\"नाम\"]))(JSONForm1.sourceData, JSONForm1.formData, JSONForm1.fieldState)}}", + "fieldType": "Text Input", + "sourceData": "John", + "isCustomField": false, + "accessor": "नाम", + "identifier": "xn__l2bm1c", + "position": 3, + "originalIdentifier": "नाम", + "iconAlign": "left", + "isDisabled": false, + "isRequired": false, + "isSpellCheck": false, + "isVisible": true, + "label": "नाम" + } + }, + "dataType": "object", + "defaultValue": "{{((sourceData, formData, fieldState) => (sourceData))(JSONForm1.sourceData, JSONForm1.formData, JSONForm1.fieldState)}}", + "fieldType": "Object", + "sourceData": { + "नाम": "John", + "суроға": { + "شارع": "Koramangala" + }, + "การศึกษา": [ + { + "କଲେଜ": "MIT" + } + ] + }, + "isCustomField": false, + "accessor": "__root_schema__", + "identifier": "__root_schema__", + "position": -1, + "originalIdentifier": "__root_schema__", + "isDisabled": false, + "isRequired": false, + "isVisible": true, + "label": "" + } + }, + "widgetName": "JSONForm1", + "submitButtonStyles": { + "buttonColor": "#03B365", + "buttonVariant": "PRIMARY" + }, + "dynamicPropertyPathList": [ + { + "key": "schema.__root_schema__.children.date_of_birth.defaultValue" + } + ], + "displayName": "JSON Form", + "iconSVG": "/static/media/icon.6bacf7df.svg", + "topRow": 3, + "bottomRow": 53, + "fieldLimitExceeded": false, + "parentRowSpace": 10, + "title": "Form", + "type": "JSON_FORM_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 18.0625, + "dynamicTriggerPathList": [], + "leftColumn": 21, + "dynamicBindingPathList": [ + { + "key": "schema.__root_schema__.defaultValue" + }, + { + "key": "schema.__root_schema__.children.xn__80a1afdk69b.children.xn__mgbuhw.defaultValue" + }, + { + "key": "schema.__root_schema__.children.xn__80a1afdk69b.defaultValue" + }, + { + "key": "schema.__root_schema__.children.xn__12ca5huag4ce3a.defaultValue" + }, + { + "key": "schema.__root_schema__.children.xn__l2bm1c.defaultValue" + } + ], + "sourceData": "", + "showReset": true, + "key": "si6k7qupn4", + "backgroundColor": "#fff", + "rightColumn": 46, + "autoGenerateForm": true, + "widgetId": "v5ddirn0i0", + "resetButtonStyles": { + "buttonColor": "#03B365", + "buttonVariant": "SECONDARY" + }, + "isVisible": true, + "version": 1, + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false, + "scrollContents": true, + "fixedFooter": true, + "disabledWhenInvalid": true, + "submitButtonLabel": "Submit", + "resetButtonLabel": "Reset" + + } + ] + } +} \ No newline at end of file diff --git a/app/client/cypress/fixtures/listdsl.json b/app/client/cypress/fixtures/listdsl.json index e0aab6c6ec..1ad7e4c89f 100644 --- a/app/client/cypress/fixtures/listdsl.json +++ b/app/client/cypress/fixtures/listdsl.json @@ -2,160 +2,323 @@ "dsl": { "widgetName": "MainContainer", "backgroundColor": "none", - "rightColumn": 1224, - "snapColumns": 16, + "rightColumn": 778, + "snapColumns": 64, "detachFromLayout": true, "widgetId": "0", "topRow": 0, - "bottomRow": 1280, + "bottomRow": 1120, "containerStyle": "none", - "snapRows": 33, + "snapRows": 125, "parentRowSpace": 1, "type": "CANVAS_WIDGET", "canExtend": true, - "version": 23, - "minHeight": 1292, + "version": 52, + "minHeight": 1550, "parentColumnSpace": 1, + "dynamicTriggerPathList": [], "dynamicBindingPathList": [], "leftColumn": 0, "children": [ - { - "isVisible": true, - "enhancements": true, - "backgroundColor": "", - "gridType": "vertical", - "gridGap": 0, - "listData": "[\n {\n \"id\": 1,\n \"email\": \"michael.lawson@reqres.in\",\n \"first_name\": \"Michael\",\n \"last_name\": \"Lawson\",\n \"avatar\": \"https://reqres.in/img/faces/7-image.jpg\"\n },\n {\n \"id\": 2,\n \"email\": \"lindsay.ferguson@reqres.in\",\n \"first_name\": \"Lindsay\",\n \"last_name\": \"Ferguson\",\n \"avatar\": \"https://reqres.in/img/faces/8-image.jpg\"\n },\n {\n \"id\": 3,\n \"email\": \"brock.lesnar@reqres.in\",\n \"first_name\": \"Brock\",\n \"last_name\": \"Lesnar\",\n \"avatar\": \"https://reqres.in/img/faces/8-image.jpg\"\n }\n]", - "widgetName": "List1", - "children": [ - { - "isVisible": true, - "widgetName": "Canvas1", - "containerStyle": "none", - "canExtend": false, - "detachFromLayout": true, - "dropDisabled": true, - "children": [ - { - "isVisible": true, - "backgroundColor": "white", - "widgetName": "Container1", - "containerStyle": "card", - "children": [ - { + { + "template": { + "Text1": { "isVisible": true, - "widgetName": "Canvas2", - "containerStyle": "none", - "canExtend": false, - "detachFromLayout": true, - "children": [ - { - "isVisible": true, - "text": "Label", - "textStyle": "LABEL", - "textAlign": "LEFT", - "widgetName": "Text1", - "type": "TEXT_WIDGET", - "isLoading": false, - "parentColumnSpace": 32, - "parentRowSpace": 40, - "leftColumn": 2, - "rightColumn": 24, - "topRow": 0, - "bottomRow": 16, - "parentId": "dinv2tsatk", - "widgetId": "k6ct7dxg4w" - }, - { - "isVisible":true, - "text":"Submit", - "buttonStyle":"PRIMARY_BUTTON", - "widgetName":"Button1", - "isDisabled":false, - "isDefaultClickDisabled":true, - "version":26, - "type":"BUTTON_WIDGET", - "isLoading":false, - "parentColumnSpace":29.25, - "parentRowSpace":40, - "leftColumn":24, - "rightColumn": 32, - "topRow":1, - "bottomRow":8, - "parentId":"dinv2tsatk", - "widgetId":"fuw9p7cuek" - } - ], - "minHeight": null, - "type": "CANVAS_WIDGET", + "text": "Label", + "fontSize": "PARAGRAPH", + "fontStyle": "BOLD", + "textAlign": "LEFT", + "textColor": "#231F20", + "truncateButtonColor": "#FFC13D", + "widgetName": "Text1", + "shouldScroll": false, + "shouldTruncate": false, + "version": 1, + "animateLoading": true, + "type": "TEXT_WIDGET", + "hideCard": false, + "displayName": "Text", + "key": "e9bpznyucj", + "iconSVG": "/static/media/icon.97c59b52.svg", + "textStyle": "HEADING", + "widgetId": "rz3yq5hf7s", + "renderMode": "CANVAS", "isLoading": false, - "parentColumnSpace": 1, - "parentRowSpace": 1, - "leftColumn": 0, - "rightColumn": null, + "leftColumn": 16, + "rightColumn": 28, "topRow": 0, - "bottomRow": null, - "parentId": "4ruj7xl5ri", - "widgetId": "dinv2tsatk" - } - ], - "dragDisabled": true, - "isDeletable": false, - "disablePropertyPane": true, - "type": "CONTAINER_WIDGET", - "isLoading": false, - "leftColumn": 0, - "rightColumn": 64, - "topRow": 0, - "bottomRow": 16, - "parentId": "0pvmmqr77m", - "widgetId": "4ruj7xl5ri" - } + "bottomRow": 4, + "parentId": "y4cy49e4l1" + }, + "Button1": { + "isVisible": true, + "animateLoading": true, + "text": "Submit", + "buttonColor": "#03B365", + "buttonVariant": "PRIMARY", + "placement": "CENTER", + "widgetName": "Button1", + "isDisabled": false, + "isDefaultClickDisabled": true, + "recaptchaType": "V3", + "version": 1, + "type": "BUTTON_WIDGET", + "hideCard": false, + "displayName": "Button", + "key": "48eoz8tblb", + "iconSVG": "/static/media/icon.cca02633.svg", + "widgetId": "lwdh6n12xy", + "renderMode": "CANVAS", + "isLoading": false, + "parentColumnSpace": 4.05078125, + "parentRowSpace": 10, + "leftColumn": 34, + "rightColumn": 50, + "topRow": 1, + "bottomRow": 5, + "parentId": "y4cy49e4l1" + } + }, + "widgetName": "List1", + "listData": "[\n {\n \"id\": 1,\n \"email\": \"michael.lawson@reqres.in\",\n \"first_name\": \"Michael\",\n \"last_name\": \"Lawson\",\n \"avatar\": \"https://reqres.in/img/faces/7-image.jpg\"\n },\n {\n \"id\": 2,\n \"email\": \"lindsay.ferguson@reqres.in\",\n \"first_name\": \"Lindsay\",\n \"last_name\": \"Ferguson\",\n \"avatar\": \"https://reqres.in/img/faces/8-image.jpg\"\n },\n {\n \"id\": 3,\n \"email\": \"brock.lesnar@reqres.in\",\n \"first_name\": \"Brock\",\n \"last_name\": \"Lesnar\",\n \"avatar\": \"https://reqres.in/img/faces/8-image.jpg\"\n },\n {\n \"id\": 4,\n \"email\": \"dwayne.jhonson@reqres.in\",\n \"first_name\": \"Dwayne\",\n \"last_name\": \"Johnson\",\n \"avatar\": \"https://reqres.in/img/faces/8-image.jpg\"\n }\n]", + "isCanvas": true, + "displayName": "List", + "iconSVG": "/static/media/icon.9925ee17.svg", + "topRow": 0, + "bottomRow": 40, + "parentRowSpace": 10, + "type": "LIST_WIDGET", + "hideCard": false, + "gridGap": 0, + "animateLoading": true, + "parentColumnSpace": 11.96875, + "dynamicTriggerPathList": [], + "leftColumn": 20, + "dynamicBindingPathList": [], + "gridType": "vertical", + "enhancements": true, + "children": [ + { + "widgetName": "Canvas1", + "displayName": "Canvas", + "topRow": 0, + "bottomRow": 400, + "parentRowSpace": 1, + "type": "CANVAS_WIDGET", + "canExtend": false, + "hideCard": true, + "dropDisabled": true, + "openParentPropertyPane": true, + "minHeight": 400, + "noPad": true, + "parentColumnSpace": 1, + "leftColumn": 0, + "children": [ + { + "boxShadow": "NONE", + "widgetName": "Container1", + "borderColor": "transparent", + "disallowCopy": true, + "isCanvas": true, + "displayName": "Container", + "iconSVG": "/static/media/icon.1977dca3.svg", + "topRow": 0, + "bottomRow": 12, + "dragDisabled": true, + "type": "CONTAINER_WIDGET", + "hideCard": false, + "openParentPropertyPane": true, + "isDeletable": false, + "animateLoading": true, + "leftColumn": 0, + "children": [ + { + "widgetName": "Canvas2", + "detachFromLayout": true, + "displayName": "Canvas", + "widgetId": "y4cy49e4l1", + "containerStyle": "none", + "topRow": 0, + "bottomRow": 70, + "parentRowSpace": 1, + "isVisible": true, + "type": "CANVAS_WIDGET", + "canExtend": false, + "version": 1, + "hideCard": true, + "parentId": "s4x8lq7c32", + "renderMode": "CANVAS", + "isLoading": false, + "parentColumnSpace": 1, + "leftColumn": 0, + "children": [ + { + "widgetName": "Text1", + "displayName": "Text", + "iconSVG": "/static/media/icon.97c59b52.svg", + "topRow": 1, + "bottomRow": 5, + "type": "TEXT_WIDGET", + "hideCard": false, + "animateLoading": true, + "dynamicTriggerPathList": [], + "dynamicBindingPathList": [], + "leftColumn": 2, + "shouldTruncate": false, + "truncateButtonColor": "#FFC13D", + "text": "Label", + "key": "e9bpznyucj", + "rightColumn": 29, + "textAlign": "LEFT", + "widgetId": "rz3yq5hf7s", + "logBlackList": { + "isVisible": true, + "text": true, + "fontSize": true, + "fontStyle": true, + "textAlign": true, + "textColor": true, + "truncateButtonColor": true, + "widgetName": true, + "shouldScroll": true, + "shouldTruncate": true, + "version": true, + "animateLoading": true, + "type": true, + "hideCard": true, + "displayName": true, + "key": true, + "iconSVG": true, + "isCanvas": true, + "textStyle": true, + "dynamicBindingPathList": true, + "dynamicTriggerPathList": true, + "minHeight": true, + "widgetId": true, + "renderMode": true, + "isLoading": true, + "parentColumnSpace": true, + "parentRowSpace": true, + "leftColumn": true, + "rightColumn": true, + "topRow": true, + "bottomRow": true, + "parentId": true + }, + "isVisible": true, + "fontStyle": "BOLD", + "textColor": "#231F20", + "shouldScroll": false, + "version": 1, + "parentId": "y4cy49e4l1", + "renderMode": "CANVAS", + "isLoading": false, + "fontSize": "PARAGRAPH", + "textStyle": "HEADING" + }, + { + "widgetName": "Button1", + "buttonColor": "#03B365", + "displayName": "Button", + "iconSVG": "/static/media/icon.cca02633.svg", + "topRow": 1, + "bottomRow": 5, + "parentRowSpace": 10, + "type": "BUTTON_WIDGET", + "hideCard": false, + "animateLoading": true, + "parentColumnSpace": 4.05078125, + "leftColumn": 34, + "text": "Submit", + "isDisabled": false, + "key": "48eoz8tblb", + "rightColumn": 53, + "isDefaultClickDisabled": true, + "widgetId": "lwdh6n12xy", + "logBlackList": { + "isVisible": true, + "animateLoading": true, + "text": true, + "buttonColor": true, + "buttonVariant": true, + "placement": true, + "widgetName": true, + "isDisabled": true, + "isDefaultClickDisabled": true, + "recaptchaType": true, + "version": true, + "type": true, + "hideCard": true, + "displayName": true, + "key": true, + "iconSVG": true, + "isCanvas": true, + "minHeight": true, + "widgetId": true, + "renderMode": true, + "isLoading": true, + "parentColumnSpace": true, + "parentRowSpace": true, + "leftColumn": true, + "rightColumn": true, + "topRow": true, + "bottomRow": true, + "parentId": true + }, + "isVisible": true, + "recaptchaType": "V3", + "version": 1, + "parentId": "y4cy49e4l1", + "renderMode": "CANVAS", + "isLoading": false, + "buttonVariant": "PRIMARY", + "placement": "CENTER" + } + ], + "key": "oiyh0dnja0" + } + ], + "borderWidth": "0", + "key": "5veqdwa6js", + "disablePropertyPane": true, + "backgroundColor": "white", + "rightColumn": 64, + "widgetId": "s4x8lq7c32", + "containerStyle": "card", + "isVisible": true, + "version": 1, + "parentId": "9qa052pga4", + "renderMode": "CANVAS", + "isLoading": false, + "borderRadius": "0" + } + ], + "key": "oiyh0dnja0", + "rightColumn": 287.25, + "detachFromLayout": true, + "widgetId": "9qa052pga4", + "containerStyle": "none", + "isVisible": true, + "version": 1, + "parentId": "0s7k5dgj77", + "renderMode": "CANVAS", + "isLoading": false + } ], - "minHeight": 400, - "type": "CANVAS_WIDGET", - "isLoading": false, - "parentColumnSpace": 1, - "parentRowSpace": 1, - "leftColumn": 0, - "rightColumn": 592, - "topRow": 0, - "bottomRow": 400, - "parentId": "5bwz8xcvhj", - "widgetId": "0pvmmqr77m" - } - ], - "type": "LIST_WIDGET", - "isLoading": false, - "parentColumnSpace": 74, - "parentRowSpace": 40, - "leftColumn": 0, - "rightColumn": 32, - "topRow": 0, - "bottomRow": 40, - "parentId": "0", - "widgetId": "5bwz8xcvhj", - "dynamicBindingPathList": [], - "template": { - "Text1": { + "privateWidgets": { + "Text1": true, + "Button1": true + }, + "key": "l1iovfl7pr", + "backgroundColor": "transparent", + "rightColumn": 44, + "itemBackgroundColor": "#FFFFFF", + "widgetId": "0s7k5dgj77", "isVisible": true, - "text": "Label", - "textStyle": "LABEL", - "textAlign": "LEFT", - "widgetName": "Text1", - "type": "TEXT_WIDGET", - "isLoading": false, - "parentColumnSpace": 32, - "parentRowSpace": 40, - "leftColumn": 0, - "rightColumn": 4, - "topRow": 0, - "bottomRow": 1, - "parentId": "dinv2tsatk", - "widgetId": "k6ct7dxg4w" - } + "parentId": "0", + "renderMode": "CANVAS", + "isLoading": false } - } ] - } +} } diff --git a/app/client/cypress/fixtures/listwidgetdsl.json b/app/client/cypress/fixtures/listwidgetdsl.json index bd01880330..f34952103f 100644 --- a/app/client/cypress/fixtures/listwidgetdsl.json +++ b/app/client/cypress/fixtures/listwidgetdsl.json @@ -1,275 +1,275 @@ { - "dsl": { - "widgetName": "MainContainer", - "backgroundColor": "none", - "rightColumn": 966, - "snapColumns": 16, - "detachFromLayout": true, - "widgetId": "0", - "topRow": 0, - "bottomRow": 800, - "containerStyle": "none", - "snapRows": 33, - "parentRowSpace": 1, - "type": "CANVAS_WIDGET", - "canExtend": true, - "version": 18, - "minHeight": 240, - "parentColumnSpace": 1, - "dynamicTriggerPathList": [], - "dynamicBindingPathList": [], - "leftColumn": 0, - "children": [ - { - "isVisible": true, - "backgroundColor": "", - "itemBackgroundColor": "white", - "gridType": "vertical", - "enhancements": true, - "gridGap": 0, - "listData": "", - "widgetName": "List1", - "children": [ - { - "isVisible": true, - "widgetName": "Canvas1", - "version": 1, - "containerStyle": "none", - "canExtend": false, - "detachFromLayout": true, - "dropDisabled": true, - "noPad": true, - "children": [ - { - "isVisible": true, - "backgroundColor": "white", - "widgetName": "Container1", - "containerStyle": "card", - "children": [ - { - "isVisible": true, - "widgetName": "Canvas2", - "version": 1, - "containerStyle": "none", - "canExtend": false, - "detachFromLayout": true, - "children": [ - { - "isVisible": true, - "defaultImage": "https://res.cloudinary.com/drako999/image/upload/v1589196259/default.png", - "imageShape": "RECTANGLE", - "maxZoomLevel": 1, - "image": "{{currentItem.img}}", - "widgetName": "Image1", - "version": 1, - "dynamicBindingPathList": [ - { - "key": "image" - } - ], - "dynamicTriggerPathList": [], - "type": "IMAGE_WIDGET", - "isLoading": false, - "leftColumn": 0, - "rightColumn": 4, - "topRow": 0, - "bottomRow": 3, - "parentId": "muh6tmsm1f", - "widgetId": "vr29m4code" - }, - { - "isVisible": true, - "text": "{{currentItem.name}}", - "fontSize": "PARAGRAPH", - "fontStyle": "BOLD", - "textAlign": "LEFT", - "textColor": "#231F20", - "widgetName": "Text1", - "version": 1, - "textStyle": "HEADING", - "dynamicBindingPathList": [ - { - "key": "text" - } - ], - "dynamicTriggerPathList": [], - "type": "TEXT_WIDGET", - "isLoading": false, - "leftColumn": 4, - "rightColumn": 10, - "topRow": 0, - "bottomRow": 1, - "parentId": "muh6tmsm1f", - "widgetId": "envgv9f2j9" - }, - { - "isVisible": true, - "text": "{{currentItem.num}}", - "fontSize": "PARAGRAPH", - "fontStyle": "BOLD", - "textAlign": "LEFT", - "textColor": "#231F20", - "widgetName": "Text2", - "version": 1, - "textStyle": "BODY", - "dynamicBindingPathList": [ - { - "key": "text" - } - ], - "dynamicTriggerPathList": [], - "type": "TEXT_WIDGET", - "isLoading": false, - "leftColumn": 4, - "rightColumn": 10, - "topRow": 1, - "bottomRow": 2, - "parentId": "muh6tmsm1f", - "widgetId": "37xbmi0bbz" - } - ], - "minHeight": null, - "type": "CANVAS_WIDGET", - "isLoading": false, - "parentColumnSpace": 1, - "parentRowSpace": 1, - "leftColumn": 0, - "rightColumn": null, - "topRow": 0, - "bottomRow": null, - "parentId": "5q9jzp3d17", - "widgetId": "muh6tmsm1f" - } - ], - "version": 1, - "dragDisabled": true, - "isDeletable": false, - "disallowCopy": true, - "disablePropertyPane": true, - "type": "CONTAINER_WIDGET", - "isLoading": false, - "leftColumn": 0, - "rightColumn": 16, - "topRow": 0, - "bottomRow": 4, - "parentId": "qt3cziyljx", - "widgetId": "5q9jzp3d17" - } - ], - "minHeight": 400, - "type": "CANVAS_WIDGET", - "isLoading": false, - "parentColumnSpace": 1, - "parentRowSpace": 1, - "leftColumn": 0, - "rightColumn": 463, - "topRow": 0, - "bottomRow": 400, - "parentId": "wmuvmnfqm0", - "widgetId": "qt3cziyljx" - } - ], - "type": "LIST_WIDGET", - "isLoading": false, - "parentColumnSpace": 57.875, - "parentRowSpace": 40, - "leftColumn": 4, - "rightColumn": 12, - "topRow": 2, - "bottomRow": 20, - "parentId": "0", - "widgetId": "wmuvmnfqm0", - "dynamicBindingPathList": [ - { - "key": "template.Image1.image" - }, - { - "key": "template.Text1.text" - }, - { - "key": "template.Text2.text" - } - ], - "template": { - "Image1": { - "isVisible": true, - "defaultImage": "https://res.cloudinary.com/drako999/image/upload/v1589196259/default.png", - "imageShape": "RECTANGLE", - "maxZoomLevel": 1, - "image": "{{List1.listData.map((currentItem) => currentItem.img)}}", - "widgetName": "Image1", - "version": 1, - "dynamicBindingPathList": [ - { - "key": "image" - } - ], - "dynamicTriggerPathList": [], - "type": "IMAGE_WIDGET", - "isLoading": false, - "leftColumn": 0, - "rightColumn": 4, - "topRow": 0, - "bottomRow": 3, - "parentId": "muh6tmsm1f", - "widgetId": "vr29m4code" - }, - "Text1": { - "isVisible": true, - "text": "{{List1.listData.map((currentItem) => currentItem.name)}}", - "fontSize": "PARAGRAPH", - "fontStyle": "BOLD", - "textAlign": "LEFT", - "textColor": "#231F20", - "widgetName": "Text1", - "version": 1, - "textStyle": "HEADING", - "dynamicBindingPathList": [ - { - "key": "text" - } - ], - "dynamicTriggerPathList": [], - "type": "TEXT_WIDGET", - "isLoading": false, - "leftColumn": 4, - "rightColumn": 10, - "topRow": 0, - "bottomRow": 1, - "parentId": "muh6tmsm1f", - "widgetId": "envgv9f2j9" - }, - "Text2": { - "isVisible": true, - "text": "{{List1.listData.map((currentItem) => currentItem.num)}}", - "fontSize": "PARAGRAPH", - "fontStyle": "BOLD", - "textAlign": "LEFT", - "textColor": "#231F20", - "widgetName": "Text2", - "version": 1, - "textStyle": "BODY", - "dynamicBindingPathList": [ - { - "key": "text" - } - ], - "dynamicTriggerPathList": [], - "type": "TEXT_WIDGET", - "isLoading": false, - "leftColumn": 4, - "rightColumn": 10, - "topRow": 1, - "bottomRow": 2, - "parentId": "muh6tmsm1f", - "widgetId": "37xbmi0bbz" - } - }, - "childAutoComplete": { - "currentItem": {} - }, - "dynamicTriggerPathList": [] - } - ] - } + "dsl": { + "widgetName": "MainContainer", + "backgroundColor": "none", + "rightColumn": 966, + "snapColumns": 16, + "detachFromLayout": true, + "widgetId": "0", + "topRow": 0, + "bottomRow": 800, + "containerStyle": "none", + "snapRows": 33, + "parentRowSpace": 1, + "type": "CANVAS_WIDGET", + "canExtend": true, + "version": 18, + "minHeight": 240, + "parentColumnSpace": 1, + "dynamicTriggerPathList": [], + "dynamicBindingPathList": [], + "leftColumn": 0, + "children": [ + { + "isVisible": true, + "backgroundColor": "", + "itemBackgroundColor": "white", + "gridType": "vertical", + "enhancements": true, + "gridGap": 0, + "listData": "", + "widgetName": "List1", + "children": [ + { + "isVisible": true, + "widgetName": "Canvas1", + "version": 1, + "containerStyle": "none", + "canExtend": false, + "detachFromLayout": true, + "dropDisabled": true, + "noPad": true, + "children": [ + { + "isVisible": true, + "backgroundColor": "white", + "widgetName": "Container1", + "containerStyle": "card", + "children": [ + { + "isVisible": true, + "widgetName": "Canvas2", + "version": 1, + "containerStyle": "none", + "canExtend": false, + "detachFromLayout": true, + "children": [ + { + "isVisible": true, + "defaultImage": "https://res.cloudinary.com/drako999/image/upload/v1589196259/default.png", + "imageShape": "RECTANGLE", + "maxZoomLevel": 1, + "image": "{{currentItem.img}}", + "widgetName": "Image1", + "version": 1, + "dynamicBindingPathList": [ + { + "key": "image" + } + ], + "dynamicTriggerPathList": [], + "type": "IMAGE_WIDGET", + "isLoading": false, + "leftColumn": 0, + "rightColumn": 4, + "topRow": 0, + "bottomRow": 3, + "parentId": "muh6tmsm1f", + "widgetId": "vr29m4code" + }, + { + "isVisible": true, + "text": "{{currentItem.name}}", + "fontSize": "PARAGRAPH", + "fontStyle": "BOLD", + "textAlign": "LEFT", + "textColor": "#231F20", + "widgetName": "Text1", + "version": 1, + "textStyle": "HEADING", + "dynamicBindingPathList": [ + { + "key": "text" + } + ], + "dynamicTriggerPathList": [], + "type": "TEXT_WIDGET", + "isLoading": false, + "leftColumn": 4, + "rightColumn": 10, + "topRow": 0, + "bottomRow": 1, + "parentId": "muh6tmsm1f", + "widgetId": "envgv9f2j9" + }, + { + "isVisible": true, + "text": "{{currentItem.email}}", + "fontSize": "PARAGRAPH", + "fontStyle": "BOLD", + "textAlign": "LEFT", + "textColor": "#231F20", + "widgetName": "Text2", + "version": 1, + "textStyle": "BODY", + "dynamicBindingPathList": [ + { + "key": "text" + } + ], + "dynamicTriggerPathList": [], + "type": "TEXT_WIDGET", + "isLoading": false, + "leftColumn": 4, + "rightColumn": 10, + "topRow": 1, + "bottomRow": 2, + "parentId": "muh6tmsm1f", + "widgetId": "37xbmi0bbz" + } + ], + "minHeight": null, + "type": "CANVAS_WIDGET", + "isLoading": false, + "parentColumnSpace": 1, + "parentRowSpace": 1, + "leftColumn": 0, + "rightColumn": null, + "topRow": 0, + "bottomRow": null, + "parentId": "5q9jzp3d17", + "widgetId": "muh6tmsm1f" + } + ], + "version": 1, + "dragDisabled": true, + "isDeletable": false, + "disallowCopy": true, + "disablePropertyPane": true, + "type": "CONTAINER_WIDGET", + "isLoading": false, + "leftColumn": 0, + "rightColumn": 16, + "topRow": 0, + "bottomRow": 4, + "parentId": "qt3cziyljx", + "widgetId": "5q9jzp3d17" + } + ], + "minHeight": 400, + "type": "CANVAS_WIDGET", + "isLoading": false, + "parentColumnSpace": 1, + "parentRowSpace": 1, + "leftColumn": 0, + "rightColumn": 463, + "topRow": 0, + "bottomRow": 400, + "parentId": "wmuvmnfqm0", + "widgetId": "qt3cziyljx" + } + ], + "type": "LIST_WIDGET", + "isLoading": false, + "parentColumnSpace": 57.875, + "parentRowSpace": 10, + "leftColumn": 4, + "rightColumn": 12, + "topRow": 2, + "bottomRow": 20, + "parentId": "0", + "widgetId": "wmuvmnfqm0", + "dynamicBindingPathList": [ + { + "key": "template.Image1.image" + }, + { + "key": "template.Text1.text" + }, + { + "key": "template.Text2.text" + } + ], + "template": { + "Image1": { + "isVisible": true, + "defaultImage": "https://res.cloudinary.com/drako999/image/upload/v1589196259/default.png", + "imageShape": "RECTANGLE", + "maxZoomLevel": 1, + "image": "{{List1.listData.map((currentItem) => currentItem.img)}}", + "widgetName": "Image1", + "version": 1, + "dynamicBindingPathList": [ + { + "key": "image" + } + ], + "dynamicTriggerPathList": [], + "type": "IMAGE_WIDGET", + "isLoading": false, + "leftColumn": 0, + "rightColumn": 4, + "topRow": 0, + "bottomRow": 3, + "parentId": "muh6tmsm1f", + "widgetId": "vr29m4code" + }, + "Text1": { + "isVisible": true, + "text": "{{List1.listData.map((currentItem) => currentItem.name)}}", + "fontSize": "PARAGRAPH", + "fontStyle": "BOLD", + "textAlign": "LEFT", + "textColor": "#231F20", + "widgetName": "Text1", + "version": 1, + "textStyle": "HEADING", + "dynamicBindingPathList": [ + { + "key": "text" + } + ], + "dynamicTriggerPathList": [], + "type": "TEXT_WIDGET", + "isLoading": false, + "leftColumn": 4, + "rightColumn": 10, + "topRow": 0, + "bottomRow": 1, + "parentId": "muh6tmsm1f", + "widgetId": "envgv9f2j9" + }, + "Text2": { + "isVisible": true, + "text": "{{List1.listData.map((currentItem) => currentItem.email)}}", + "fontSize": "PARAGRAPH", + "fontStyle": "BOLD", + "textAlign": "LEFT", + "textColor": "#231F20", + "widgetName": "Text2", + "version": 1, + "textStyle": "BODY", + "dynamicBindingPathList": [ + { + "key": "text" + } + ], + "dynamicTriggerPathList": [], + "type": "TEXT_WIDGET", + "isLoading": false, + "leftColumn": 4, + "rightColumn": 10, + "topRow": 1, + "bottomRow": 2, + "parentId": "muh6tmsm1f", + "widgetId": "37xbmi0bbz" + } + }, + "childAutoComplete": { + "currentItem": {} + }, + "dynamicTriggerPathList": [] + } + ] + } } diff --git a/app/client/cypress/fixtures/mongo_GET_Actions.json b/app/client/cypress/fixtures/mongo_GET_Actions.json index 987c073313..f039e2eda7 100644 --- a/app/client/cypress/fixtures/mongo_GET_Actions.json +++ b/app/client/cypress/fixtures/mongo_GET_Actions.json @@ -29,17 +29,41 @@ "encodeParamsToggle": true, "formData": { "updateMany": { - "limit": "SINGLE" + "limit": { + "data": "SINGLE", + "componentData": "SINGLE", + "viewType": "form" + } }, "insert": { - "documents": "{\n \"genres\": {{insert_col_input1.text}}, \n \"homepage\": {{insert_col_input2.text}}, \n \"imdb_id\": {{insert_col_input3.text}}, \n \"poster_path\": {{insert_col_input4.text}}\n}" + "documents": { + "data": "{\n \"genres\": {{insert_col_input1.text}}, \n \"homepage\": {{insert_col_input2.text}}, \n \"imdb_id\": {{insert_col_input3.text}}, \n \"poster_path\": {{insert_col_input4.text}}\n}", + "componentData": "{\n \"genres\": {{insert_col_input1.text}}, \n \"homepage\": {{insert_col_input2.text}}, \n \"imdb_id\": {{insert_col_input3.text}}, \n \"poster_path\": {{insert_col_input4.text}}\n}", + "viewType": "form" + } + }, + "collection": { + "data": "movies", + "componentData": "movies", + "viewType": "form" }, - "collection": "movies", "delete": { - "limit": "SINGLE" + "limit": { + "data": "SINGLE", + "componentData": "SINGLE", + "viewType": "form" + } }, - "command": "INSERT", - "smartSubstitution": true + "command": { + "data": "INSERT", + "componentData": "INSERT", + "viewType": "form" + }, + "smartSubstitution": { + "data": true, + "componentData": true, + "viewType": "form" + } } }, "executeOnLoad": false, @@ -83,19 +107,47 @@ "actionConfiguration": { "timeoutInMillisecond": 10000, "paginationType": "NONE", - "path": "template_table/{{data_table.selectedRow._ref}}", "encodeParamsToggle": true, "formData": { + "path": { + "data": "template_table/{{data_table.selectedRow._ref}}", + "componentData": "template_table/{{data_table.selectedRow._ref}}", + "viewType": "form" + }, "updateMany": { - "limit": "SINGLE" + "limit": { + "data": "SINGLE", + "componentData": "SINGLE", + "viewType": "form" + } }, - "collection": "movies", + "collection": { + "data": "movies", + "componentData": "movies", + "viewType": "form" + }, "delete": { - "query": "{ _id: ObjectId('{{data_table.triggeredRow._id}}') }", - "limit": "SINGLE" + "query": { + "data": "{ _id: ObjectId('{{data_table.triggeredRow._id}}') }", + "componentData": "{ _id: ObjectId('{{data_table.triggeredRow._id}}') }", + "viewType": "form" + }, + "limit": { + "data": "SINGLE", + "componentData": "SINGLE", + "viewType": "form" + } }, - "command": "DELETE", - "smartSubstitution": "DELETE_DOCUMENT" + "command": { + "data": "DELETE", + "componentData": "DELETE", + "viewType": "form" + }, + "smartSubstitution": { + "data": "DELETE_DOCUMENT", + "componentData": "DELETE_DOCUMENT", + "viewType": "form" + } } }, "executeOnLoad": false, @@ -140,20 +192,56 @@ "encodeParamsToggle": true, "formData": { "updateMany": { - "limit": "SINGLE" + "limit": { + "data": "SINGLE", + "componentData": "SINGLE", + "viewType": "form" + } }, "find": { - "query": "{ homepage: /{{data_table.searchText||\"\"}}/i }", - "limit": "{{data_table.pageSize}}", - "skip": "{{(data_table.pageNo - 1) * data_table.pageSize}}", - "sort": "{ \n{{key_select.selectedOptionValue}}: {{order_select.selectedOptionValue}} \n}" + "query": { + "data": "{ homepage: /{{data_table.searchText||\"\"}}/i }", + "componentData": "{ homepage: /{{data_table.searchText||\"\"}}/i }", + "viewType": "form" + }, + "limit": { + "data": "{{data_table.pageSize}}", + "componentData": "{{data_table.pageSize}}", + "viewType": "form" + }, + "skip": { + "data": "{{(data_table.pageNo - 1) * data_table.pageSize}}", + "componentData": "{{(data_table.pageNo - 1) * data_table.pageSize}}", + "viewType": "form" + }, + "sort": { + "data": "{ \n{{key_select.selectedOptionValue}}: {{order_select.selectedOptionValue}} \n}", + "componentData": "{ \n{{key_select.selectedOptionValue}}: {{order_select.selectedOptionValue}} \n}", + "viewType": "form" + } }, - "collection": "movies", + "collection": { + "data": "movies", + "componentData": "movies", + "viewType": "form" + }, "delete": { - "limit": "SINGLE" + "limit": { + "data": "SINGLE", + "componentData": "SINGLE", + "viewType": "form" + } }, - "command": "FIND", - "smartSubstitution": false + "command": { + "data": "FIND", + "componentData": "FIND", + "viewType": "form" + }, + "smartSubstitution": { + "data": false, + "componentData": false, + "viewType": "form" + } } }, "executeOnLoad": true, @@ -201,16 +289,44 @@ "encodeParamsToggle": true, "formData": { "updateMany": { - "query": "{ _id: ObjectId('{{data_table.selectedRow._id}}') }", - "limit": "SINGLE", - "update": "{\n \"genres\" : {{update_col_1.text}},\n\t\"homepage\" : {{update_col_2.text}},\n \"imdb_id\" : {{update_col_3.text}},\n \"poster_path\" : {{update_col_4.text}}\n}" + "query": { + "data": "{ _id: ObjectId('{{data_table.selectedRow._id}}') }", + "componentData": "{ _id: ObjectId('{{data_table.selectedRow._id}}') }", + "viewType": "form" + }, + "limit": { + "data": "SINGLE", + "componentData": "SINGLE", + "viewType": "form" + }, + "update": { + "data": "{\n \"genres\" : {{update_col_1.text}},\n\t\"homepage\" : {{update_col_2.text}},\n \"imdb_id\" : {{update_col_3.text}},\n \"poster_path\" : {{update_col_4.text}}\n}", + "componentData": "{\n \"genres\" : {{update_col_1.text}},\n\t\"homepage\" : {{update_col_2.text}},\n \"imdb_id\" : {{update_col_3.text}},\n \"poster_path\" : {{update_col_4.text}}\n}", + "viewType": "form" + } }, - "collection": "movies", + "collection": { + "data": "movies", + "componentData": "movies", + "viewType": "form" + }, "delete": { - "limit": "SINGLE" + "limit": { + "data": "SINGLE", + "componentData": "SINGLE", + "viewType": "form" + } }, - "command": "UPDATE", - "smartSubstitution": true + "command": { + "data": "UPDATE", + "componentData": "UPDATE", + "viewType": "form" + }, + "smartSubstitution": { + "data": true, + "componentData": true, + "viewType": "form" + } } }, "executeOnLoad": false, diff --git a/app/client/cypress/fixtures/omnibarDsl.json b/app/client/cypress/fixtures/omnibarDsl.json new file mode 100644 index 0000000000..3a7a1ed84e --- /dev/null +++ b/app/client/cypress/fixtures/omnibarDsl.json @@ -0,0 +1,59 @@ +{ + "dsl": { + "widgetName": "MainContainer", + "backgroundColor": "none", + "rightColumn": 816, + "snapColumns": 64, + "detachFromLayout": true, + "widgetId": "0", + "topRow": 0, + "bottomRow": 360, + "containerStyle": "none", + "snapRows": 125, + "parentRowSpace": 1, + "type": "CANVAS_WIDGET", + "canExtend": true, + "version": 53, + "minHeight": 340, + "parentColumnSpace": 1, + "dynamicTriggerPathList": [], + "dynamicBindingPathList": [], + "leftColumn": 0, + "children": [ + { + "isVisible": true, + "animateLoading": true, + "text": "{{appsmith}}", + "buttonColor": "#03B365", + "buttonVariant": "PRIMARY", + "placement": "CENTER", + "widgetName": "Button1", + "isDisabled": false, + "isDefaultClickDisabled": true, + "recaptchaType": "V3", + "version": 1, + "type": "BUTTON_WIDGET", + "hideCard": false, + "displayName": "Button", + "key": "shydybeo1d", + "iconSVG": "/static/media/icon.cca02633.svg", + "widgetId": "llztjclhrm", + "renderMode": "CANVAS", + "isLoading": false, + "parentColumnSpace": 12.5625, + "parentRowSpace": 10, + "leftColumn": 21, + "rightColumn": 37, + "topRow": 18, + "bottomRow": 22, + "parentId": "0", + "dynamicBindingPathList": [ + { + "key": "text" + } + ], + "dynamicTriggerPathList": [] + } + ] + } + } \ No newline at end of file diff --git a/app/client/cypress/integration/Smoke_TestSuite/Application/ImportExportForkApplication_spec.js b/app/client/cypress/integration/Smoke_TestSuite/Application/ImportExportForkApplication_spec.js index d3552e116e..392575d7a6 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/Application/ImportExportForkApplication_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/Application/ImportExportForkApplication_spec.js @@ -1,14 +1,12 @@ -/// - -import homePage from "../../../locators/HomePage"; -//const dsl = require("../../../fixtures/forkedApp.json"); +const homePage = require("../../../locators/HomePage"); +const reconnectDatasourceModal = require("../../../locators/ReconnectLocators"); describe("Import, Export and Fork application and validate data binding", function() { let orgid; let appid; let newOrganizationName; - - it("1. Import application and validate data on pageload", function() { + let appName; + it("Import application from json and validate data on pageload", function() { // import application cy.get(homePage.homeIcon).click(); cy.get(homePage.optionsIcon) @@ -16,45 +14,48 @@ describe("Import, Export and Fork application and validate data binding", functi .click(); cy.get(homePage.orgImportAppOption).click({ force: true }); cy.get(homePage.orgImportAppModal).should("be.visible"); - cy.xpath(homePage.uploadLogo) - .attachFile("forkedApp.json") - .wait(500); - cy.get(homePage.orgImportAppButton) - .trigger("click") - .wait(500); - cy.get(homePage.orgImportAppModal).should("not.exist"); - + cy.xpath(homePage.uploadLogo).attachFile("forkedApp.json"); cy.wait("@importNewApplication").then((interception) => { - let appId = interception.response.body.data.id; - let defaultPage = interception.response.body.data.pages.find( - (eachPage) => !!eachPage.isDefault, - ); - - cy.get(homePage.toastMessage).should( - "contain", - "Application imported successfully", - ); + cy.wait(100); + // should check reconnect modal openning + const { isPartialImport } = interception.response.body.data; + if (isPartialImport) { + // should reconnect button + cy.get(reconnectDatasourceModal.Modal).should("be.visible"); + cy.get(reconnectDatasourceModal.SkipToAppBtn).click({ force: true }); + cy.wait(2000); + } else { + cy.get(homePage.toastMessage).should( + "contain", + "Application imported successfully", + ); + } const uuid = () => Cypress._.random(0, 1e4); const name = uuid(); + appName = `app${name}`; + cy.get(homePage.applicationName).click({ force: true }); + cy.get(`${homePage.applicationEditMenu} li:first-child a`).click({ + force: true, + }); cy.wait(2000); cy.get(homePage.applicationName) - .clear() - .type(`app${name}`); + // .clear() + .type(appName); cy.wrap(`app${name}`).as("appname"); cy.wait(2000); // validating data binding for the imported application cy.xpath("//input[@value='Submit']").should("be.visible"); cy.xpath("//div[text()='schema_name']").should("be.visible"); - cy.xpath("//div[text()='pg_toast']").should("be.visible"); + cy.xpath("//div[text()='id']").should("be.visible"); cy.xpath("//div[text()='title']").should("be.visible"); - cy.xpath("//div[text()='Recusan']").should("be.visible"); + cy.xpath("//div[text()='due']").should("be.visible"); }); }); - it("2. Fork application and validate data binding for the widgets", function() { + it("Fork application and validate data binding for the widgets", function() { // fork application cy.get(homePage.homeIcon).click(); - cy.get(homePage.searchInput).type(`${this.appname}`); + cy.get(homePage.searchInput).type(`${appName}`); cy.wait(2000); cy.get(homePage.applicationCard) .first() @@ -68,16 +69,16 @@ describe("Import, Export and Fork application and validate data binding", functi // validating data binding for the forked application cy.xpath("//input[@value='Submit']").should("be.visible"); cy.xpath("//div[text()='schema_name']").should("be.visible"); - cy.xpath("//div[text()='pg_toast']").should("be.visible"); + cy.xpath("//div[text()='id']").should("be.visible"); cy.xpath("//div[text()='title']").should("be.visible"); - cy.xpath("//div[text()='Recusan']").should("be.visible"); + cy.xpath("//div[text()='due']").should("be.visible"); }); - it("3. Export and import application and validate data binding for the widgets", function() { + it("Export and import application and validate data binding for the widgets", function() { cy.NavigateToHome(); cy.get(homePage.searchInput) .clear() - .type(`${this.appname}`); + .type(`${appName}`); cy.wait(2000); cy.get(homePage.applicationCard) .first() @@ -94,7 +95,7 @@ describe("Import, Export and Fork application and validate data binding", functi expect(headers).to.have.property("content-type", "application/json"); expect(headers).to.have.property( "content-disposition", - `attachment; filename*=UTF-8''${this.appname}.json`, + `attachment; filename*=UTF-8''${appName}.json`, ); cy.writeFile("cypress/fixtures/exportedApp.json", body, "utf-8"); cy.generateUUID().then((uid) => { @@ -107,29 +108,46 @@ describe("Import, Export and Fork application and validate data binding", functi cy.get(homePage.orgImportAppOption).click({ force: true }); cy.get(homePage.orgImportAppModal).should("be.visible"); - cy.xpath(homePage.uploadLogo).attachFile("exportedApp.json"); + cy.get(".t--import-json-card input").attachFile("exportedApp.json"); // import exported application in new organization - cy.get(homePage.orgImportAppButton).click({ force: true }); + // cy.get(homePage.orgImportAppButton).click({ force: true }); cy.wait("@importNewApplication").then((interception) => { - let appId = interception.response.body.data.id; - let defaultPage = interception.response.body.data.pages.find( - (eachPage) => !!eachPage.isDefault, - ); - cy.get(homePage.toastMessage).should( - "contain", - "Application imported successfully", - ); - // validating data binding for imported application - cy.xpath("//input[@value='Submit']").should("be.visible"); - cy.xpath("//div[text()='schema_name']").should("be.visible"); - cy.xpath("//div[text()='pg_toast']").should("be.visible"); - cy.xpath("//div[text()='title']").should("be.visible"); - cy.xpath("//div[text()='Recusan']").should("be.visible"); + const { isPartialImport } = interception.response.body.data; + if (isPartialImport) { + // should reconnect button + cy.get(reconnectDatasourceModal.Modal).should("be.visible"); + cy.get(reconnectDatasourceModal.SkipToAppBtn).click({ + force: true, + }); + cy.wait(2000); + } else { + cy.get(homePage.toastMessage).should( + "contain", + "Application imported successfully", + ); + } + const importedApp = interception.response.body.data.application; + const appSlug = importedApp.slug; + cy.wait("@getPagesForCreateApp").then((interception) => { + const pages = interception.response.body.data.pages; + let defaultPage = pages.find( + (eachPage) => !!eachPage.isDefault, + ); + // validating data binding for imported application + cy.xpath("//input[@value='Submit']").should("be.visible"); + cy.xpath("//div[text()='schema_name']").should("be.visible"); + // cy.xpath("//div[text()='information_schema']").should( + // "be.visible", + // ); + cy.xpath("//div[text()='id']").should("be.visible"); + cy.xpath("//div[text()='title']").should("be.visible"); + cy.xpath("//div[text()='due']").should("be.visible"); - cy.url().should( - "include", - `/applications/${appId}/pages/${defaultPage.id}/edit`, - ); + cy.url().should( + "include", + `/${appSlug}/${defaultPage.slug}-${defaultPage.id}/edit`, + ); + }); }); }); }); diff --git a/app/client/cypress/integration/Smoke_TestSuite/Application/MongoDBShoppingCart_spec.js b/app/client/cypress/integration/Smoke_TestSuite/Application/MongoDBShoppingCart_spec.js index 9d6f9d1692..3853d2d985 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/Application/MongoDBShoppingCart_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/Application/MongoDBShoppingCart_spec.js @@ -16,7 +16,6 @@ describe("Shopping cart App", function() { it("1. Create MongoDB datasource and add Insert, Find, Update and Delete queries", function() { cy.NavigateToDatasourceEditor(); cy.get(datasource.MongoDB).click(); - cy.getPluginFormsAndCreateDatasource(); cy.fillMongoDatasourceForm(); cy.testSaveDatasource(); cy.get("@createDatasource").then((httpResponse) => { @@ -32,16 +31,14 @@ describe("Shopping cart App", function() { cy.get(".CodeEditorTarget") .first() .type("Productnames"); - // cy.get(".CodeEditorTarget") - // .eq(1) - // .type("{}"); + cy.assertPageSave(); cy.get(appPage.dropdownChevronLeft).click(); // EditProducts query to update the cart cy.get(queryLocators.createQuery) .last() .click(); cy.get(queryLocators.queryNameField).type("EditProducts"); - cy.get("[data-cy='actionConfiguration.formData.command']").click(); + cy.get("[data-cy='actionConfiguration.formData.command.data']").click(); cy.get(".t--dropdown-option") .eq(2) .click(); @@ -56,23 +53,22 @@ describe("Shopping cart App", function() { cy.get(".CodeEditorTarget") .eq(2) .type( - `{ - "title" : "{{title.text}}", + `{"title" : "{{title.text}}", "description" :"{{description.text}}", "price" : {{price.text}}, - "quantity":{{quantity.text}} - `, + "quantity":{{quantity.text}}`, { parseSpecialCharSequences: false, }, ); + cy.assertPageSave(); cy.get(appPage.dropdownChevronLeft).click(); // Add product query cy.get(queryLocators.createQuery) .last() .click(); cy.get(queryLocators.queryNameField).type("AddProduct"); - cy.get("[data-cy='actionConfiguration.formData.command']").click(); + cy.get("[data-cy='actionConfiguration.formData.command.data']").click(); cy.get(".t--dropdown-option") .eq(1) .click(); @@ -82,21 +78,20 @@ describe("Shopping cart App", function() { cy.get(".CodeEditorTarget") .eq(1) .type( - `[{ - "title" : "{{Title.text}}", + `[{"title" : "{{Title.text}}", "description": "{{Description.text}}", "price" : {{Price.text}}, - "quantity" : {{Quantity.text}} - `, + "quantity" : {{Quantity.text}}`, { parseSpecialCharSequences: false }, ); + cy.assertPageSave(); cy.get(appPage.dropdownChevronLeft).click(); // delete product cy.get(queryLocators.createQuery) .last() .click(); cy.get(queryLocators.queryNameField).type("DeleteProduct"); - cy.get("[data-cy='actionConfiguration.formData.command']").click(); + cy.get("[data-cy='actionConfiguration.formData.command.data']").click(); cy.get(".t--dropdown-option") .eq(3) .click(); @@ -108,6 +103,8 @@ describe("Shopping cart App", function() { .type('{"title":"{{Table1.selectedRow.title}}"}', { parseSpecialCharSequences: false, }); + cy.assertPageSave(); + cy.get(appPage.dropdownChevronLeft).click(); cy.get(appPage.dropdownChevronLeft).click(); }); @@ -161,6 +158,8 @@ describe("Shopping cart App", function() { .closest("div") .eq(0) .click(); + cy.assertPageSave(); + cy.wait(5000); // validating updated value in the cart cy.get(".selected-row") .children() diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ActiveDatasource/ActiveDatasource.spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ActiveDatasource/ActiveDatasource_spec.js similarity index 63% rename from app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ActiveDatasource/ActiveDatasource.spec.js rename to app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ActiveDatasource/ActiveDatasource_spec.js index 8584dd2973..2b4350f3c4 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ActiveDatasource/ActiveDatasource.spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ActiveDatasource/ActiveDatasource_spec.js @@ -1,14 +1,14 @@ const datasourceEditor = require("../../../../locators/DatasourcesEditor.json"); -const queryEditor = require("../../../../locators/QueryEditor.json"); let datasourceName, actionName; -describe("Google Sheet datasource test cases", function() { +describe("Mongo Active datasource test cases", function() { before(() => { cy.NavigateToDatasourceEditor(); - cy.get(datasourceEditor.googleSheets).click(); + cy.get(datasourceEditor.MongoDB).click(); cy.getPluginFormsAndCreateDatasource(); - cy.fillGoogleSheetsDatasourceForm(); - cy.get("@createDatasource").then((httpResponse) => { + cy.fillMongoDatasourceForm(); + cy.get(datasourceEditor.saveBtn).click({ force: true }); + cy.wait("@createDatasource").then((httpResponse) => { datasourceName = httpResponse.response.body.data.name; cy.NavigateToActiveDSQueryPane(datasourceName); }); @@ -21,20 +21,14 @@ describe("Google Sheet datasource test cases", function() { it("Create a new query from the datasource editor", function() { cy.NavigateToActiveTab(); cy.get( - `.t--datasource-name:contains('${datasourceName}') .t--queries-for-SAAS`, + `.t--datasource-name:contains('${datasourceName}') .t--queries-for-DB`, ).should("have.text", "1 query on this page"); }); after(() => { cy.CheckAndUnfoldEntityItem("QUERIES/JS"); cy.get(`.t--entity-name:contains('${actionName}')`).click(); - cy.get(queryEditor.queryMoreAction).click(); - cy.get(queryEditor.deleteUsingContext).click(); - cy.wait("@deleteAction").should( - "have.nested.property", - "response.body.responseMeta.status", - 200, - ); + cy.deleteQueryUsingContext(); cy.deleteDatasource(datasourceName); }); }); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ApiPaneTests/API_Edit_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ApiPaneTests/API_Edit_spec.js index 648dfe66be..867876a756 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ApiPaneTests/API_Edit_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ApiPaneTests/API_Edit_spec.js @@ -53,7 +53,7 @@ describe("API Panel Test Functionality", function() { cy.get(apiwidget.runQueryButton).click(); cy.get(".bp3-dialog") .find("button") - .contains("Cancel") + .contains("No") .click(); cy.get(apiwidget.runQueryButton) .children() diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ApiPaneTests/API_all_sidebar_actions_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ApiPaneTests/API_all_sidebar_actions_spec.js index e6d477d267..cb3e4c51bb 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ApiPaneTests/API_all_sidebar_actions_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ApiPaneTests/API_all_sidebar_actions_spec.js @@ -1,6 +1,11 @@ const commonlocators = require("../../../../locators/commonlocators.json"); const testdata = require("../../../../fixtures/testdata.json"); const apiwidget = require("../../../../locators/apiWidgetslocator.json"); +const { + AggregateHelper, +} = require("../../../../support/Pages/AggregateHelper"); + +const helper = new AggregateHelper(); describe("API Panel Test Functionality ", function() { it("Test API copy/Move/delete feature", function() { @@ -11,23 +16,25 @@ describe("API Panel Test Functionality ", function() { cy.CreateAPI("FirstAPI"); cy.enterDatasourceAndPath(testdata.baseUrl, "{{ '/random' }}"); cy.log("Creation of FirstAPI Action successful"); - //cy.GlobalSearchEntity("FirstAPI"); - cy.xpath('//*[local-name()="g" and @id="Icon/Outline/more-vertical"]') - .last() - .should("be.hidden") - .invoke("show") - .click({ force: true }); - cy.copyEntityToPage("SecondPage"); + helper.ActionContextMenuByEntityName( + "FirstAPI", + "Copy to page", + "SecondPage", + ); // click on learn how link cy.get(".t--learn-how-apis-link").click(); // this should open in a global search modal cy.get(commonlocators.globalSearchModal); cy.get("body").click(0, 0); - cy.MoveAPIToPage("Page1"); + helper.ActionContextMenuByEntityName( + "FirstAPICopy", + "Move to page", + "Page1", + ); + cy.wait(2000); cy.get(".t--entity-name") .contains("FirstAPICopy") .click({ force: true }); cy.get(apiwidget.resourceUrl).should("contain.text", "{{ '/random' }}"); - cy.DeleteAPIFromSideBar(); }); }); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Applications/ApplicationURL_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Applications/ApplicationURL_spec.js new file mode 100644 index 0000000000..342725b93f --- /dev/null +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Applications/ApplicationURL_spec.js @@ -0,0 +1,114 @@ +import homePage from "../../../../locators/HomePage"; +const explorer = require("../../../../locators/explorerlocators.json"); +describe("Slug URLs", () => { + let applicationName; + let applicationId; + it("Checks URL redirection from legacy URLs to slug URLs", () => { + applicationId = localStorage.getItem("applicationId"); + cy.location("pathname").then((pathname) => { + const pageId = pathname + .split("/")[2] + ?.split("-") + .pop(); + cy.visit(`/applications/${applicationId}/pages/${pageId}/edit`).then( + () => { + cy.wait(10000); + cy.location("pathname").then((pathname) => { + const pageId = pathname + .split("/")[2] + ?.split("-") + .pop(); + const appName = localStorage.getItem("AppName"); + expect(pathname).to.be.equal(`/${appName}/page1-${pageId}/edit`); + }); + }, + ); + }); + }); + + it("Checks if application slug updates on the URL when application name changes", () => { + cy.generateUUID().then((appName) => { + applicationName = appName; + cy.AppSetupForRename(); + cy.get(homePage.applicationName).type(`${appName}` + "{enter}"); + cy.wait("@updateApplication").should( + "have.nested.property", + "response.body.responseMeta.status", + 200, + ); + cy.location("pathname").then((pathname) => { + const pageId = pathname + .split("/")[2] + ?.split("-") + .pop(); + expect(pathname).to.be.equal(`/${appName}/page1-${pageId}/edit`); + }); + }); + }); + + it("Checks if page slug updates on the URL when page name changes", () => { + cy.GlobalSearchEntity("Page1"); + // cy.RenameEntity("Page renamed"); + cy.get(`.t--entity-item:contains(Page1)`).within(() => { + cy.get(".t--context-menu").click({ force: true }); + }); + cy.selectAction("Edit Name"); + cy.get(explorer.editEntity) + .last() + .type("Page renamed", { force: true }); + cy.get("body").click(0, 0); + cy.wait("@updatePage").should( + "have.nested.property", + "response.body.responseMeta.status", + 200, + ); + cy.location("pathname").then((pathname) => { + const pageId = pathname + .split("/")[2] + ?.split("-") + .pop(); + expect(pathname).to.be.equal( + `/${applicationName}/page-renamed-${pageId}/edit`, + ); + }); + }); + + it("Check the url of old applications and upgrades version", () => { + cy.request("PUT", `/api/v1/applications/${applicationId}`, { + applicationVersion: 1, + }).then((response) => { + const application = response.body.data; + expect(application.applicationVersion).to.equal(1); + cy.NavigateToHome(); + cy.reload(); + + cy.SearchApp(applicationName); + + cy.wait("@getPagesForCreateApp").then((intercept) => { + const { application, pages } = intercept.response.body.data; + const defaultPage = pages.find((p) => p.isDefault); + + cy.location().should((loc) => { + expect(loc.pathname).includes( + `/applications/${application.id}/pages/${defaultPage.id}`, + ); + }); + + cy.get(".t--upgrade").click({ force: true }); + + cy.get(".t--upgrade-confirm").click({ force: true }); + + cy.wait("@getPagesForCreateApp").then((intercept) => { + const { application, pages } = intercept.response.body.data; + const defaultPage = pages.find((p) => p.isDefault); + + cy.location().should((loc) => { + expect(loc.pathname).includes( + `/${application.slug}/${defaultPage.slug}-${defaultPage.id}`, + ); + }); + }); + }); + }); + }); +}); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Applications/DuplicateApplication_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Applications/DuplicateApplication_spec.js index 890793583a..5fbb8d1012 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Applications/DuplicateApplication_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Applications/DuplicateApplication_spec.js @@ -33,19 +33,29 @@ describe("Duplicate application", function() { .click({ force: true }); cy.get(homePage.duplicateApp).click({ force: true }); // eslint-disable-next-line cypress/no-unnecessary-waiting - cy.wait(4000); - cy.wait("@getPage").should( - "have.nested.property", - "response.body.responseMeta.status", - 200, - ); - cy.get("@getPage").then((httpResponse) => { - duplicateApplicationDsl = httpResponse.response.body.data.layouts[0].dsl; - cy.log(JSON.stringify(duplicateApplicationDsl)); - cy.log(JSON.stringify(parentApplicationDsl)); - expect(JSON.stringify(duplicateApplicationDsl)).to.deep.equal( - JSON.stringify(parentApplicationDsl), + + cy.wait("@cloneApp").then((httpResponse) => { + const application = httpResponse.response.body.data; + cy.wait(4000); + cy.wait("@getPage").should( + "have.nested.property", + "response.body.responseMeta.status", + 200, ); + cy.get("@getPage").then((httpResponse) => { + const page = httpResponse.response.body.data; + duplicateApplicationDsl = + httpResponse.response.body.data.layouts[0].dsl; + cy.log(JSON.stringify(duplicateApplicationDsl)); + cy.log(JSON.stringify(parentApplicationDsl)); + expect(JSON.stringify(duplicateApplicationDsl)).to.deep.equal( + JSON.stringify(parentApplicationDsl), + ); + cy.url().should( + "include", + `/${application.slug}/${page.slug}-${page.id}`, + ); + }); }); }); }); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Applications/ForkApplication_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Applications/ForkApplication_spec.js index a480cb640d..0f5e4bff00 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Applications/ForkApplication_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Applications/ForkApplication_spec.js @@ -1,7 +1,5 @@ const dsl = require("../../../../fixtures/basicDsl.json"); import homePage from "../../../../locators/HomePage"; -const commonlocators = require("../../../../locators/commonlocators.json"); -const widgetsPage = require("../../../../locators/Widgets.json"); let forkedApplicationDsl; let parentApplicationDsl; diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Binding/BindButton_Text_WithRecaptcha_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Binding/BindButton_Text_WithRecaptcha_spec.js new file mode 100644 index 0000000000..58a27a3fdf --- /dev/null +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Binding/BindButton_Text_WithRecaptcha_spec.js @@ -0,0 +1,38 @@ +const commonlocators = require("../../../../locators/commonlocators.json"); +const formWidgetsPage = require("../../../../locators/FormWidgets.json"); +const dsl = require("../../../../fixtures/buttonRecaptchaDsl.json"); +const pages = require("../../../../locators/Pages.json"); +const widgetsPage = require("../../../../locators/Widgets.json"); +const publish = require("../../../../locators/publishWidgetspage.json"); +const testdata = require("../../../../fixtures/testdata.json"); + +describe("Binding the Button widget with Text widget using Recpatcha v3", function() { + before(() => { + cy.addDsl(dsl); + }); + + it("Validate the Button binding with Text Widget with Recaptcha Token", function() { + cy.get("button") + .contains("Submit") + .should("be.visible") + .click({ force: true }); + cy.SearchEntityandOpen("Text1"); + cy.get(".t--draggable-textwidget .bp3-ui-text").should("be.visible"); + cy.get(".t--draggable-textwidget .bp3-ui-text").should("have.value", ""); + cy.SearchEntityandOpen("Button1"); + cy.get(".t--property-control-googlerecaptchaversion .bp3-popover-target") + .last() + .should("be.visible") + .click({ force: true }); + cy.get(".t--dropdown-option:contains('reCAPTCHA v2')").click({ + force: true, + }); + cy.get("button") + .contains("Submit") + .should("be.visible") + .click({ force: true }); + cy.SearchEntityandOpen("Text1"); + cy.get(".t--draggable-textwidget .bp3-ui-text").should("be.visible"); + cy.get(".t--draggable-textwidget .bp3-ui-text").should("have.value", ""); + }); +}); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Binding/Bind_API_with_List_Widget_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Binding/Bind_API_with_List_Widget_spec.js index f27344fd8d..079fc24989 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Binding/Bind_API_with_List_Widget_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Binding/Bind_API_with_List_Widget_spec.js @@ -32,7 +32,7 @@ describe("Test Create Api and Bind to Table widget", function() { it("Test_Validate the Api data is updated on List widget", function() { cy.SearchEntityandOpen("List1"); cy.testJsontext("items", "{{Api1.data.users}}"); - cy.get(".t--draggable-textwidget span").should("have.length.gte", 8); + cy.get(".t--draggable-textwidget span").should("have.length", 8); cy.get(".t--draggable-textwidget span") .first() .invoke("text") @@ -50,7 +50,7 @@ describe("Test Create Api and Bind to Table widget", function() { }, ).then(() => cy.wait(500)); - cy.get(".t--widget-textwidget span").should("have.length.gte", 8); + cy.get(".t--widget-textwidget span").should("have.length", 8); cy.get(".t--widget-textwidget span") .first() .invoke("text") @@ -63,7 +63,7 @@ describe("Test Create Api and Bind to Table widget", function() { cy.get(publishPage.backToEditor).click({ force: true }); cy.SearchEntityandOpen("List1"); cy.testJsontext("itemspacing\\(px\\)", "50"); - cy.get(".t--draggable-textwidget span").should("have.length.gte", 6); + cy.get(".t--draggable-textwidget span").should("have.length", 6); cy.get(".t--draggable-textwidget span") .first() .invoke("text") @@ -79,7 +79,7 @@ describe("Test Create Api and Bind to Table widget", function() { interval: 1000, }, ).then(() => cy.wait(500)); - cy.get(".t--widget-textwidget span").should("have.length.gte", 6); + cy.get(".t--widget-textwidget span").should("have.length", 6); cy.get(".t--widget-textwidget span") .first() .invoke("text") diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Binding/JSObjectToInput_Spec.ts b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Binding/JSObjectToInput_Spec.ts index 620421f048..257ae1e40b 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Binding/JSObjectToInput_Spec.ts +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Binding/JSObjectToInput_Spec.ts @@ -15,7 +15,7 @@ describe("Validate Create Api and Bind to Table widget via JSObject", () => { it("1. Bind Input widget with JSObject", function () { jsEditor.CreateJSObject('return "Success";', false); - agHelper.SelectEntityByName("WIDGETS")//to expand widgets + agHelper.expandCollapseEntity("WIDGETS")//to expand widgets agHelper.expandCollapseEntity("Form1") agHelper.SelectEntityByName("Input2") cy.get("@jsObjName").then((jsObjName) => { diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Binding/Promises_Spec.ts b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Binding/Promises_Spec.ts index b3115ca38f..611689957b 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Binding/Promises_Spec.ts +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Binding/Promises_Spec.ts @@ -15,7 +15,7 @@ describe("Validate basic operations on Entity explorer JSEditor structure", () = cy.fixture('promisesBtnDsl').then((val: any) => { agHelper.AddDsl(val) }); - agHelper.SelectEntityByName("WIDGETS")//to expand widgets + agHelper.expandCollapseEntity("WIDGETS")//to expand widgets agHelper.SelectEntityByName("Button1"); jsEditor.EnterJSContext('onclick', "{{storeValue('date', Date()).then(() => showAlert(appsmith.store.date))}}", true, true); agHelper.ClickButton('Submit') @@ -29,7 +29,7 @@ describe("Validate basic operations on Entity explorer JSEditor structure", () = cy.fixture("promisesBtnDsl").then((val: any) => { agHelper.AddDsl(val); }); - agHelper.SelectEntityByName("WIDGETS"); + agHelper.expandCollapseEntity("WIDGETS"); agHelper.SelectEntityByName("Button1"); jsEditor.EnterJSContext( "onclick", @@ -61,7 +61,7 @@ describe("Validate basic operations on Entity explorer JSEditor structure", () = key: "name", value: "{{this.params.country}}", }); // verifies Bug 10055 - agHelper.SelectEntityByName("WIDGETS"); + agHelper.expandCollapseEntity("WIDGETS"); agHelper.SelectEntityByName("Button1"); jsEditor.EnterJSContext( "onclick", @@ -93,7 +93,7 @@ describe("Validate basic operations on Entity explorer JSEditor structure", () = "https://source.unsplash.com/collection/8439505", "Christmas", ); - agHelper.SelectEntityByName("WIDGETS"); //to expand widgets + agHelper.expandCollapseEntity("WIDGETS"); //to expand widgets agHelper.SelectEntityByName("Button1"); jsEditor.EnterJSContext( "onclick", @@ -108,7 +108,7 @@ describe("Validate basic operations on Entity explorer JSEditor structure", () = true, ); agHelper.SelectEntityByName("Image1"); - jsEditor.EnterJSContext("image", `{{ Christmas.data }}`, true); + jsEditor.EnterJSContext("image", `{{Christmas.data}}`, true); agHelper.WaitUntilEleDisappear( locator._toastMsg, "will be executed automatically on page load", @@ -126,7 +126,7 @@ describe("Validate basic operations on Entity explorer JSEditor structure", () = apiPage.CreateAndFillApi("https://favqs.com/api/qotd", "InspiringQuotes"); jsEditor.CreateJSObject(`const user = 'You'; return InspiringQuotes.run().then((res) => { showAlert("Today's quote for " + user + " is " + JSON.stringify(res.quote.body), 'success') }).catch(() => showAlert("Unable to fetch quote for " + user, 'warning'))`); - agHelper.SelectEntityByName("WIDGETS"); //to expand widgets + agHelper.expandCollapseEntity("WIDGETS"); //to expand widgets agHelper.SelectEntityByName("Button1"); cy.get("@jsObjName").then((jsObjName) => { jsEditor.EnterJSContext('onclick', "{{" + jsObjName + ".myFun1()}}", true, true); @@ -137,35 +137,20 @@ return InspiringQuotes.run().then((res) => { showAlert("Today's quote for " + us .should("contain.text", "Today's quote for You"); }); - //Skipping until this bug is closed! - it.skip("6. Bug 9782: Verify .then & .catch (show alert should trigger) via JS Objects without return keyword", () => { - cy.fixture('promisesBtnDsl').then((val: any) => { - agHelper.AddDsl(val) - }); - jsEditor.CreateJSObject(`const user = 'You'; -InspiringQuotes.run().then((res) => { showAlert("Today's quote for " + user + " is " + JSON.stringify(res.quote.body), 'success') }).catch(() => showAlert("Unable to fetch quote for " + user, 'warning'))`); - agHelper.SelectEntityByName("Button1"); - cy.get("@jsObjName").then((jsObjName) => { - jsEditor.EnterJSContext('onclick', "{{" + jsObjName + ".myFun1()}}", true, true); - }); - agHelper.ClickButton('Submit') - cy.get(locator._toastMsg).should("have.length", 1).should("contain.text", "Today's quote for You"); - }); - - it("7. Verify Promise.race via direct Promises", () => { + it("6. Verify Promise.race via direct Promises", () => { cy.fixture('promisesBtnDsl').then((val: any) => { agHelper.AddDsl(val) }); apiPage.CreateAndFillApi("https://api.agify.io?name={{this.params.person}}", "Agify") apiPage.ValidateQueryParams({ key: "name", value: "{{this.params.person}}" }); // verifies Bug 10055 - agHelper.SelectEntityByName("WIDGETS") + agHelper.expandCollapseEntity("WIDGETS") agHelper.SelectEntityByName("Button1"); jsEditor.EnterJSContext('onclick', `{{ Promise.race([Agify.run({ person: 'Melinda' }), Agify.run({ person: 'Trump' })]).then((res) => { showAlert('Winner is ' + JSON.stringify(res.name), 'success') }) }} `, true, true); agHelper.ClickButton('Submit') cy.get(locator._toastMsg).should("have.length", 1).contains(/Melinda|Trump/g) }) - it("8. Verify maintaining context via direct Promises", () => { + it("7. Verify maintaining context via direct Promises", () => { cy.fixture("promisesBtnListDsl").then((val: any) => { agHelper.AddDsl(val); }); @@ -173,7 +158,7 @@ InspiringQuotes.run().then((res) => { showAlert("Today's quote for " + user + " "https://api.jikan.moe/v3/search/anime?q={{this.params.name}}", "GetAnime", ); - agHelper.SelectEntityByName("WIDGETS"); //to expand widgets + agHelper.expandCollapseEntity("WIDGETS"); //to expand widgets agHelper.SelectEntityByName("List1"); jsEditor.EnterJSContext( "items", @@ -218,11 +203,11 @@ InspiringQuotes.run().then((res) => { showAlert("Today's quote for " + user + " .should("have.text", "Showing results for : fruits basket : the final"); }); - it("9: Verify Promise.all via direct Promises", () => { + it("8: Verify Promise.all via direct Promises", () => { cy.fixture('promisesBtnDsl').then((val: any) => { agHelper.AddDsl(val) }); - agHelper.SelectEntityByName("WIDGETS")//to expand widgets + agHelper.expandCollapseEntity("WIDGETS")//to expand widgets agHelper.SelectEntityByName("Button1"); jsEditor.EnterJSContext('onclick', `{{ (function () { @@ -239,60 +224,74 @@ InspiringQuotes.run().then((res) => { showAlert("Today's quote for " + user + " cy.get(locator._toastMsg).should("have.length", 1).should("have.text", "cat,dog,camel,rabbit,rat") }); - //Skipping until this bug is closed! - - it.skip("10. Bug 10150: Verify Promise.all via JSObjects", () => { + it("9. Bug 10150: Verify Promise.all via JSObjects", () => { let date = new Date().toDateString(); cy.fixture('promisesBtnDsl').then((val: any) => { agHelper.AddDsl(val) }); jsEditor.CreateJSObject(`let allFuncs = [Genderize.run({ country: 'India' }), RandomUser.run(), -GetAnime.run({ name: 'Odd Taxi' }), +GetAnime.run({ name: 'Gintama' }), InspiringQuotes.run(), Agify.run({ person: 'Scripty' }), Christmas.run() ] -return Promise.all(allFuncs).then(() => showAlert("Wonderful! all apis executed", "success")).catch(() => showAlert("Please check your api's again", "error")); `) +showAlert("Running all api's", "warning"); +return Promise.all(allFuncs).then(() => +showAlert("Wonderful! all apis executed", "success")).catch(() => showAlert("Please check your api's again", "error")); `) - // apiPage.CreateAndFillApi("https://api.agify.io?name={{this.params.person}}", "Agify") - // apiPage.ValidateQueryParams({ key: "name", value: "{{this.params.person}}" }); // verifies Bug 10055 - agHelper.SelectEntityByName("WIDGETS") + agHelper.expandCollapseEntity("WIDGETS") agHelper.SelectEntityByName("Button1"); cy.get("@jsObjName").then((jsObjName) => { - jsEditor.EnterJSContext('onclick', "{{storeValue('date', Date()).then(() => { showAlert(appsmith.store.date, 'success'); " + jsObjName + ".myFun1()})}}", true, true); + jsEditor.EnterJSContext('onclick', "{{storeValue('date', Date()).then(() => { showAlert(appsmith.store.date, 'success'); return " + jsObjName + ".myFun1()})}}", true, true); }); agHelper.ClickButton('Submit') - cy.get(locator._toastMsg).should("have.length", 2) - cy.get(locator._toastMsg).first().should('contain.text', date) + agHelper.WaitUntilEleAppear(locator._toastMsg) + cy.get(locator._toastMsg).should("have.length", 3) + cy.get(locator._toastMsg).eq(0).should('contain.text', date) + cy.get(locator._toastMsg).eq(1).contains("Running all api's") + agHelper.WaitUntilEleAppear(locator._toastMsg) cy.get(locator._toastMsg).last().contains(/Wonderful|Please check/g) }); - //To skip until clarified - it.skip("11. Verify Promises.any via direct Promises", () => { + it("10. Verify Promises.any via direct JSObjects", () => { cy.fixture('promisesBtnDsl').then((val: any) => { agHelper.AddDsl(val) }); + jsEditor.CreateJSObject(`export default { + func2: async () => { + return Promise.reject(new Error('fail')).then(showAlert("Promises reject from func2")); + }, + func1: async () => { + showAlert("In func1") + return "func1" + }, + func3: async () => { + showAlert("In func3") + return "func3" + }, + runAny: async () => { + return Promise.any([this.func2(), this.func3(), this.func1()]).then((value) => showAlert("Resolved promise is:" + value)) + } + }`, true, true) + agHelper.expandCollapseEntity('WIDGETS') agHelper.SelectEntityByName("Button1"); - jsEditor.EnterJSContext('onclick', `{{ - const promise1 = Promise.reject(0); - const promise2 = new Promise((resolve) => setTimeout(resolve, 100, 'quick')); - const promise3 = new Promise((resolve) => setTimeout(resolve, 500, 'slow')); - const promises = [promise1, promise2, promise3]; - Promise.any(promises).then((value) => showAlert("Resolved promise is:" + value)); - }} `, true, true); + cy.get("@jsObjName").then((jsObjName) => { + jsEditor.EnterJSContext('onclick', "{{" + jsObjName + ".runAny()}}", true, true); + }); agHelper.ClickButton('Submit') cy.get(locator._toastMsg) - .should("have.length", 1) - .should("contain.text", "We are on planet Earth"); + .should("have.length", 4) + cy.get(locator._toastMsg).eq(0).contains('Promises reject from func2') + cy.get(locator._toastMsg).last().contains('Resolved promise is:func3') }); - it("12. Verify resetWidget via .then direct Promises", () => { + it("11. Bug : 11110 - Verify resetWidget via .then direct Promises", () => { cy.fixture("promisesBtnDsl").then((dsl: any) => { agHelper.AddDsl(dsl); }); - agHelper.SelectEntityByName("WIDGETS"); //to expand widgets + agHelper.expandCollapseEntity("WIDGETS"); //to expand widgets agHelper.SelectEntityByName("Button1"); jsEditor.EnterJSContext( "onclick", @@ -310,6 +309,21 @@ return Promise.all(allFuncs).then(() => showAlert("Wonderful! all apis executed" agHelper.NavigateBacktoEditor() }) + //Skipping until this bug this is addressed! + it.skip("12. Bug 9782: Verify .then & .catch (show alert should trigger) via JS Objects without return keyword", () => { + cy.fixture('promisesBtnDsl').then((val: any) => { + agHelper.AddDsl(val) + }); + jsEditor.CreateJSObject(`const user = 'You'; +InspiringQuotes.run().then((res) => { showAlert("Today's quote for " + user + " is " + JSON.stringify(res.quote.body), 'success') }).catch(() => showAlert("Unable to fetch quote for " + user, 'warning'))`); + agHelper.SelectEntityByName("Button1"); + cy.get("@jsObjName").then((jsObjName) => { + jsEditor.EnterJSContext('onclick', "{{" + jsObjName + ".myFun1()}}", true, true); + }); + agHelper.ClickButton('Submit') + cy.get(locator._toastMsg).should("have.length", 1).should("contain.text", "Today's quote for You"); + }); + }) diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Binding/TextTable_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Binding/TextTable_spec.js index 5ff64f705a..a1cc427b39 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Binding/TextTable_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Binding/TextTable_spec.js @@ -33,7 +33,7 @@ describe("Text-Table Binding Functionality", function() { .find("span") .click(); cy.EvaluateDataType("string"); - cy.EvaluateCurrentValue(tabValue); + cy.validateEvaluatedValue(tabValue); cy.PublishtheApp(); cy.isSelectRow(1); cy.readTabledataPublish("1", "0").then((tabDataP) => { @@ -61,7 +61,7 @@ describe("Text-Table Binding Functionality", function() { .find("span") .click(); cy.EvaluateDataType("string"); - cy.EvaluateCurrentValue(tabValue); + cy.validateEvaluatedValue(tabValue); cy.PublishtheApp(); cy.isSelectRow(2); cy.readTabledataPublish("2", "1").then((tabDataP) => { @@ -86,7 +86,7 @@ describe("Text-Table Binding Functionality", function() { .find("span") .click(); cy.EvaluateDataType("string"); - cy.EvaluateCurrentValue(listingCount); + cy.validateEvaluatedValue(listingCount); cy.PublishtheApp(); cy.get(publish.tableLength) .find(".tr") @@ -139,7 +139,7 @@ describe("Text-Table Binding Functionality", function() { .find("span") .click(); cy.EvaluateDataType("string"); - cy.EvaluateCurrentValue(tabValue); + cy.validateEvaluatedValue(tabValue); cy.PublishtheApp(); cy.isSelectRow(1); cy.readTabledataPublish("1", "2").then((tabDataP) => { diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Comments/AddComments_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Comments/AddComments_spec.js index 408b93feed..aadc2436a5 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Comments/AddComments_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Comments/AddComments_spec.js @@ -2,7 +2,6 @@ import commentsLocators from "../../../../locators/CommentsLocators"; const commonLocators = require("../../../../locators/commonlocators.json"); import homePage from "../../../../locators/HomePage"; const dsl = require("../../../../fixtures/basicDsl.json"); -const { typeIntoDraftEditor } = require("./utils"); const newCommentText1 = "new comment text 1"; let commentThreadId; @@ -59,7 +58,7 @@ describe("Comments", function() { cy.wait(1000); cy.get(commonLocators.canvas).click(50, 50); - typeIntoDraftEditor(commentsLocators.mentionsInput, newCommentText1); + cy.typeIntoDraftEditor(commentsLocators.mentionsInput, newCommentText1); cy.get(commentsLocators.mentionsInput).type("{enter}"); // when user adds first comment, following command will count for the headers of the comment card // in case of "Skip Tour" this has to be 2. @@ -96,7 +95,7 @@ describe("Comments", function() { cy.get(commentsLocators.switchToCommentModeBtn).click({ force: true }); cy.get(commonLocators.canvas).click(50, 50); - typeIntoDraftEditor(commentsLocators.mentionsInput, newCommentText1); + cy.typeIntoDraftEditor(commentsLocators.mentionsInput, newCommentText1); cy.get(commentsLocators.mentionsInput).type("{enter}"); cy.get("[data-cy=comments-card-header]") .its("length") @@ -110,7 +109,7 @@ describe("Comments", function() { // wait for transition to be completed // eslint-disable-next-line cypress/no-unnecessary-waiting cy.wait(300); - typeIntoDraftEditor(commentsLocators.mentionsInput, newCommentText1); + cy.typeIntoDraftEditor(commentsLocators.mentionsInput, newCommentText1); cy.get(commentsLocators.mentionsInput).type("{enter}"); cy.wait("@createNewThread").then((response) => { commentThreadId = response.response.body.data.id; diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Comments/utils.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Comments/utils.js deleted file mode 100644 index 799b5e2600..0000000000 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Comments/utils.js +++ /dev/null @@ -1,12 +0,0 @@ -export function typeIntoDraftEditor(selector, text) { - cy.get(selector).then((input) => { - var textarea = input.get(0); - textarea.dispatchEvent(new Event("focus")); - - var textEvent = document.createEvent("TextEvent"); - textEvent.initTextEvent("textInput", true, true, null, text); - textarea.dispatchEvent(textEvent); - - textarea.dispatchEvent(new Event("blur")); - }); -} diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/ChartDataPoint_Spec.ts b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/ChartDataPoint_Spec.ts index d7c7ff25fd..42ad725063 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/ChartDataPoint_Spec.ts +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/ChartDataPoint_Spec.ts @@ -21,7 +21,7 @@ describe("Input widget test with default value from chart datapoint", () => { }); it("1. Input widget test with default value from another Input widget", () => { - agHelper.SelectEntityByName("WIDGETS") + agHelper.expandCollapseEntity("WIDGETS") agHelper.SelectEntityByName("Input1") jsEditor.EnterJSContext("defaulttext", dataSet.bindChartData + "}}"); agHelper.ValidateNetworkCallRespPut('@updateLayout') diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/DocumentViewer_Spec.ts b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/DocumentViewer_Spec.ts index b6dc52340d..8b1f0d9aca 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/DocumentViewer_Spec.ts +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/DocumentViewer_Spec.ts @@ -11,7 +11,7 @@ describe("DocumentViewer Widget Functionality", () => { it("2. Modify visibility & Publish app & verify", () => { agHelper.NavigateToExplorer(); - cy.CheckAndUnfoldEntityItem("WIDGETS"); //to expand widgets + agHelper.expandCollapseEntity("WIDGETS"); //to expand widgets agHelper.SelectEntityByName("DocumentViewer1"); agHelper.ToggleOrDisable("visible", false); agHelper.DeployApp(); @@ -22,7 +22,7 @@ describe("DocumentViewer Widget Functionality", () => { }); it("3. Change visibility & Publish app & verify again", () => { - cy.CheckAndUnfoldEntityItem("WIDGETS"); //to expand widgets + agHelper.expandCollapseEntity("WIDGETS"); //to expand widgets agHelper.SelectEntityByName("DocumentViewer1"); agHelper.ToggleOrDisable("visible"); agHelper.DeployApp(); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/Dropdown_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/Dropdown_spec.js index cb628053f0..1d550d9ca0 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/Dropdown_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/Dropdown_spec.js @@ -66,12 +66,11 @@ describe("Dropdown Widget Functionality", function() { ); }); - it.skip("should check that Objects can be added to Select Widget default value", () => { + it("should check that Objects can be added to Select Widget default value", () => { cy.openPropertyPane("selectwidget"); cy.updateCodeInput( ".t--property-control-options", - `[ - { + `[{ "label": "Blue", "value": "BLUE" }, @@ -82,25 +81,16 @@ describe("Dropdown Widget Functionality", function() { { "label": "Red", "value": "RED" - } - ]`, - ); - cy.updateCodeInput( - ".t--property-control-defaultvalue", - ` - { - "label": "Green", - "value": "GREEN" - } - `, + }]`, ); + cy.updateCodeInput(".t--property-control-defaultvalue", "BLUE"); cy.get(".t--property-control-options .t--codemirror-has-error").should( "not.exist", ); cy.get(".t--property-control-defaultvalue .t--codemirror-has-error").should( "not.exist", ); - cy.get(formWidgetsPage.dropdownDefaultButton).should("contain", "Green"); + cy.get(formWidgetsPage.dropdownDefaultButton).should("contain", "Blue"); }); it("Dropdown Functionality To Check disabled Widget", function() { diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/IconButton_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/IconButton_spec.js index b0e2e7fa22..85e605c03a 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/IconButton_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/IconButton_spec.js @@ -1,23 +1,26 @@ const dsl = require("../../../../fixtures/iconButtonWidgetsDsl.json"); const formWidgetsPage = require("../../../../locators/FormWidgets.json"); +const commonlocators = require("../../../../locators/commonlocators.json"); +const widgetsPage = require("../../../../locators/Widgets.json"); +const publishPage = require("../../../../locators/publishWidgetspage.json"); describe("Icon Button Widget Functionality", function() { before(() => { cy.addDsl(dsl); }); - it("check default buttonVariant with isJSConvertible", function() { + it("1. check default buttonVariant with isJSConvertible", function() { cy.openPropertyPane("iconbuttonwidget"); cy.get(formWidgetsPage.toggleButtonVariant).click(); - cy.get(".t--draggable-iconbuttonwidget button").should( + cy.get(widgetsPage.iconWidgetBtn).should( "have.css", "background-color", "rgb(3, 179, 101)", ); }); - it("add space into buttonVariant and validate", function() { + it("2. add space into buttonVariant and validate", function() { cy.get(".t--property-control-buttonvariant .CodeMirror textarea") .first() .focus() @@ -35,10 +38,38 @@ describe("Icon Button Widget Functionality", function() { "PRIMARY ", ); - cy.get(".t--draggable-iconbuttonwidget button").should( + cy.get(widgetsPage.iconWidgetBtn).should( "have.css", "background-color", "rgb(3, 179, 101)", ); }); + + it("3. show alert on button click", function() { + cy.get(".t--property-control-onclick") + .find(".t--js-toggle") + .click({ force: true }); + + cy.testJsontext( + "onclick", + "{{showAlert('Icon Button Clicked','success')}}", + ); + + cy.get(widgetsPage.iconWidgetBtn).click({ force: true }); + cy.get(commonlocators.toastmsg).contains("Icon Button Clicked"); + cy.PublishtheApp(); + cy.get(publishPage.iconWidgetBtn).click({ force: true }); + cy.get(commonlocators.toastmsg).contains("Icon Button Clicked"); + cy.goToEditFromPublish(); + }); + + it("4. should not show alert onclick if button is disabled", function() { + cy.openPropertyPane("iconbuttonwidget"); + cy.CheckWidgetProperties(commonlocators.disableCheckbox); + cy.get(widgetsPage.iconWidgetBtn).click({ force: true }); + cy.get(commonlocators.toastmsg).should("not.exist"); + cy.PublishtheApp(); + cy.get(publishPage.iconWidgetBtn).click({ force: true }); + cy.get(commonlocators.toastmsg).should("not.exist"); + }); }); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/Inputv2_inside_List_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/Inputv2_inside_List_spec.js new file mode 100644 index 0000000000..42c0a3c733 --- /dev/null +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/Inputv2_inside_List_spec.js @@ -0,0 +1,189 @@ +const explorer = require("../../../../locators/explorerlocators.json"); +const dsl = require("../../../../fixtures/InputWidgetV2InsideListDSL.json"); + +const widgetName = "inputwidgetv2"; +const widgetInput = `.t--widget-${widgetName} input`; + +describe("Input widget V2 - ", () => { + before(() => { + cy.addDsl(dsl); + }); + + it("1. Validate input widget resets OnSubmit", () => { + cy.openPropertyPane(widgetName); + cy.get( + ".t--property-control-onsubmit .t--open-dropdown-Select-Action", + ).click(); + cy.selectShowMsg(); + cy.addSuccessMessage("Submitted!!"); + cy.get(widgetInput).clear({ force: true }); + cy.wait(300); + cy.get(widgetInput).type("test{enter}"); //Clicking enter submits the form here + cy.wait(300); + cy.get(widgetInput).should("contain.value", ""); + }); + + it("2. Validate DataType - TEXT can be entered into Input widget", () => { + [ + { + input: "test", + expected: "test:true:false", + }, + { + input: "test123", + expected: "test123:true:false", + }, + { + input: "123", + expected: "123:true:false", + }, + { + input: "", + expected: ":true:false", + }, + { + input: "$100.22", + expected: "$100.22:true:false", + }, + { + input: "test@appsmith.com", + expected: "test@appsmith.com:true:false", + }, + ].forEach(({ expected, input }) => enterAndTest(input, expected)); + }); + + it("3. Validate DataType - NUMBER can be entered into Input widget", () => { + cy.openPropertyPane(widgetName); + cy.selectDropdownValue(".t--property-control-datatype", "Number"); + + cy.get(".t--property-control-required label") + .last() + .click({ force: true }); + + cy.selectDropdownValue(".t--property-control-datatype", "Number"); + [ + { + input: "invalid", + expected: "null:true:false", + }, + { + input: "invalid123", + expected: "123:true:false", + }, + { + input: "123", + expected: "123:true:false", + }, + { + input: "-", + expected: "null:true:false", + }, + { + input: "", + expected: "null:true:false", + }, + { + input: "$100.22", + expected: "100.22:true:false", + }, + { + input: "invalid@appsmith.com", + expected: "null:true:false", + }, + { + input: "1.001", + expected: "1.001:true:false", + }, + { + input: "1.1.", + expected: "null:true:false", + }, + ].forEach(({ expected, input }) => enterAndTest(input, expected)); + }); + + it("4. Validate DataType - PASSWORD can be entered into Input widget", () => { + cy.openPropertyPane(widgetName); + cy.selectDropdownValue(".t--property-control-datatype", "Password"); + [ + { + input: "test", + expected: "test:true:false", + }, + { + input: "test123", + expected: "test123:true:false", + }, + { + input: "123", + expected: "123:true:false", + }, + { + input: "-", + expected: "-:true:false", + }, + { + input: "", + expected: ":true:false", + }, + { + input: "$100.22", + expected: "$100.22:true:false", + }, + { + input: "test@appsmith.com", + expected: "test@appsmith.com:true:false", + }, + ].forEach(({ expected, input }) => enterAndTest(input, expected)); + }); + + it("5. Validate DataType - EMAIL can be entered into Input widget", () => { + cy.openPropertyPane(widgetName); + cy.selectDropdownValue(".t--property-control-datatype", "Email"); + + cy.get(".t--property-control-required label") + .last() + .click({ force: true }); + + [ + { + input: "test", + expected: "test:true:false", + }, + { + input: "test123", + expected: "test123:true:false", + }, + { + input: "123", + expected: "123:true:false", + }, + { + input: "-", + expected: "-:true:false", + }, + { + input: "", + expected: ":true:false", + }, + { + input: "$100.22", + expected: "$100.22:true:false", + }, + { + input: "test@appsmith.com", + expected: "test@appsmith.com:true:false", + }, + ].forEach(({ expected, input }) => enterAndTest(input, expected)); + }); + + function enterAndTest(text, expected) { + cy.get(`.t--widget-${widgetName} input`).clear({ force: true }); + cy.wait(300); + if (text) { + cy.get(`.t--widget-${widgetName} input`) + .click() + .type(text); + } + cy.get(".t--widget-textwidget").should("contain", expected); + } +}); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/List_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/List_spec.js index 417b355790..3fffe2de6a 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/List_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/List_spec.js @@ -8,7 +8,7 @@ describe("List Widget Functionality", function() { }); it("should validate that restricted widgets cannot be added to List", () => { - cy.get(explorer.addWidget).click(); + cy.get(explorer.widgetSwitchId).click(); const allowed = [ "audiowidget", diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/Migration_Spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/Migration_Spec.js index 639e5cfced..bbda807719 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/Migration_Spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/Migration_Spec.js @@ -15,16 +15,16 @@ describe("Migration Validate", function() { cy.xpath(homePage.uploadLogo) .attachFile("TableMigrationAppExported.json") .wait(500); - cy.get(homePage.orgImportAppButton) - .trigger("click") - .wait(500); + // cy.get(homePage.orgImportAppButton) + // .trigger("click") + // .wait(500); cy.get(homePage.orgImportAppModal).should("not.exist"); cy.wait("@importNewApplication").then((interception) => { - let appId = interception.response.body.data.id; - let defaultPage = interception.response.body.data.pages.find( - (eachPage) => !!eachPage.isDefault, - ); + // let appId = interception.response.body.data.id; + // let defaultPage = interception.response.body.data.pages.find( + // (eachPage) => !!eachPage.isDefault, + // ); cy.get(homePage.toastMessage).should( "contain", diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/MultiSelect_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/MultiSelect_spec.js index 7f435bdacc..6ac1122316 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/MultiSelect_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/MultiSelect_spec.js @@ -102,4 +102,42 @@ describe("MultiSelect Widget Functionality", function() { .first() .should("have.text", "Green"); }); + it("should display the right label", () => { + cy.openPropertyPane("multiselectwidgetv2"); + cy.updateCodeInput( + ".t--property-control-options", + `[ + { + "label": "Blue", + "value": "BLUE" + }, + { + "label": "Green", + "value": "GREEN" + }, + { + "label": "Red", + "value": "RED" + } + ]`, + ); + cy.updateCodeInput( + ".t--property-control-defaultvalue", + `[ + "GREEN", + "RED" + ]`, + ); + cy.get(".t--property-control-options .t--codemirror-has-error").should( + "not.exist", + ); + cy.get(".t--property-control-defaultvalue .t--codemirror-has-error").should( + "not.exist", + ); + cy.wait(100); + cy.get(formWidgetsPage.multiselectwidgetv2) + .find(".rc-select-selection-item-content") + .first() + .should("have.text", "Green"); + }); }); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/Switchgroup_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/Switchgroup_spec.js index 7db7b7b9b8..803bd848db 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/Switchgroup_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/Switchgroup_spec.js @@ -4,15 +4,24 @@ const explorer = require("../../../../locators/explorerlocators.json"); describe("Switchgroup Widget Functionality", function() { before(() => { cy.addDsl(dsl); + cy.wait(5000); }); - it("Add new widget", () => { + it("1. Add a new switch group widget with others", () => { cy.get(explorer.addWidget).click(); cy.dragAndDropToCanvas("switchgroupwidget", { x: 300, y: 300 }); cy.get(".t--widget-switchgroupwidget").should("exist"); + cy.dragAndDropToCanvas("checkboxgroupwidget", { x: 300, y: 500 }); + cy.get(".t--widget-checkboxgroupwidget").should("exist"); + cy.dragAndDropToCanvas("textwidget", { x: 300, y: 700 }); + cy.get(".t--widget-textwidget").should("exist"); + cy.updateCodeInput( + ".t--property-control-text", + `{{SwitchGroup1.selectedValues}}`, + ); }); - it("should check that empty value is allowed in options", () => { + it("2. Should check that empty value is allowed in options", () => { cy.openPropertyPane("switchgroupwidget"); cy.updateCodeInput( ".t--property-control-options", @@ -36,7 +45,7 @@ describe("Switchgroup Widget Functionality", function() { ); }); - it("should check that more thatn empty value is not allowed in options", () => { + it("3. Should check that more thatn empty value is not allowed in options", () => { cy.openPropertyPane("switchgroupwidget"); cy.updateCodeInput( ".t--property-control-options", @@ -59,4 +68,49 @@ describe("Switchgroup Widget Functionality", function() { "exist", ); }); + + it("4. Setting selectedValues to undefined does not crash the app", () => { + // Reset options for switch group + cy.openPropertyPane("switchgroupwidget"); + cy.updateCodeInput( + ".t--property-control-options", + `[ + { + "label": "Blue", + "value": "BLUE" + }, + { + "label": "Green", + "value": "GREEN" + }, + { + "label": "Red", + "value": "RED" + } + ]`, + ); + // throw a cyclic dependency error from checkbox group + cy.openPropertyPane("checkboxgroupwidget"); + cy.get(".t--property-control-options input") + .eq(1) + .click({ force: true }) + .type("{{BLUE}}", { parseSpecialCharSequences: false }); + + cy.get(".t--property-control-options") + .find(".t--js-toggle") + .trigger("click") + .wait(1000); + // wait for a cyclic dependency error to occur + cy.validateToastMessage("Cyclic dependency found while evaluating"); + // check if a crash messsge is appeared + cy.get(".t--widget-switchgroupwidget") + .contains("Oops, Something went wrong.") + .should("not.exist"); + cy.wait(1000); + // check if the evaluation is disabled + cy.get(".t--widget-textwidget").should( + "contain", + `{{SwitchGroup1.selectedValues}}`, + ); + }); }); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/Table_Color_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/Table_Color_spec.js new file mode 100644 index 0000000000..44f1f860b2 --- /dev/null +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/Table_Color_spec.js @@ -0,0 +1,78 @@ +const widgetsPage = require("../../../../locators/Widgets.json"); +const dsl = require("../../../../fixtures/tableNewDsl.json"); +const publish = require("../../../../locators/publishWidgetspage.json"); + +describe("Table Widget property pane feature validation", function() { + before(() => { + cy.addDsl(dsl); + }); + + it("1. Test to validate text color and text background", function() { + // Open property pane + cy.openPropertyPane("tablewidget"); + // Click on text color input field + cy.get(widgetsPage.textColor) + .first() + .click({ force: true }); + // Select green color + cy.get(widgetsPage.greenColor) + .last() + .click(); + // eslint-disable-next-line cypress/no-unnecessary-waiting + cy.wait(500); + cy.wait("@updateLayout"); + // Verify the text color is green + cy.readTabledataValidateCSS("1", "0", "color", "rgb(3, 179, 101)"); + // Change the text color and enter purple in input field + cy.get(widgetsPage.textColor) + .scrollIntoView() + .clear({ force: true }) + .type("purple", { force: true }); + cy.wait("@updateLayout"); + // Verify the text color is purple + cy.readTabledataValidateCSS("1", "0", "color", "rgb(128, 0, 128)"); + // Click on cell background color + cy.get(`${widgetsPage.cellBackground} input`) + .first() + .scrollIntoView() + .click({ force: true }); + // eslint-disable-next-line cypress/no-unnecessary-waiting + cy.wait(500); + // select the green color + cy.get(widgetsPage.greenColor) + .last() + .click(); + cy.wait("@updateLayout"); + cy.assertPageSave(); + cy.PublishtheApp(); + cy.wait(4000); + + // Verify the cell background color is green + cy.readTabledataValidateCSS( + "1", + "1", + "background-color", + "rgb(3, 179, 101)", + ); + cy.get(publish.backToEditor).click(); + cy.openPropertyPane("tablewidget"); + + // Change the cell background color and enter purple in input field + cy.get(`${widgetsPage.cellBackground} input`) + .clear({ force: true }) + .type("purple", { force: true }); + cy.wait("@updateLayout"); + cy.assertPageSave(); + cy.PublishtheApp(); + cy.wait(4000); + + // Verify the cell background color is purple + cy.readTabledataValidateCSS( + "1", + "1", + "background-color", + "rgb(128, 0, 128)", + ); + cy.get(publish.backToEditor).click(); + }); +}); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/Table_FilteredTableData_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/Table_FilteredTableData_spec.js new file mode 100644 index 0000000000..b3704d1a2b --- /dev/null +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/Table_FilteredTableData_spec.js @@ -0,0 +1,58 @@ +const widgetsPage = require("../../../../locators/Widgets.json"); +const commonlocators = require("../../../../locators/commonlocators.json"); +const publish = require("../../../../locators/publishWidgetspage.json"); +const dsl = require("../../../../fixtures/tableAndTextDsl.json"); + +describe("Table Widget Filtered Table Data in autocomplete", function() { + before(() => { + cy.addDsl(dsl); + }); + + it("Table Widget Functionality", function() { + cy.openPropertyPane("tablewidget"); + cy.wait("@updateLayout"); + }); + + it("Table Widget Functionality To Filter and search data", function() { + cy.get(publish.searchInput) + .first() + .type("query"); + cy.get(publish.filterBtn).click(); + cy.get(publish.attributeDropdown).click(); + cy.get(publish.attributeValue) + .contains("task") + .click(); + cy.get(publish.conditionDropdown).click(); + cy.get(publish.attributeValue) + .contains("contains") + .click(); + cy.get(publish.inputValue).type("bind"); + cy.wait(500); + cy.get(widgetsPage.filterApplyBtn).click({ force: true }); + cy.wait(500); + cy.get(".t--close-filter-btn").click({ force: true }); + }); + + it("Table Widget Functionality to validate filtered table data", function() { + cy.SearchEntityandOpen("Text1"); + cy.testJsontext("text", "{{Table1.filteredTableData[0].task}}"); + cy.readTabledata("0", "1").then((tabData) => { + const tableData = tabData; + cy.get(commonlocators.labelTextStyle).should("have.text", tableData); + }); + }); + + it("Table Widget Functionality to validate filtered table data with actual table data", function() { + cy.readTabledata("0", "1").then((tabData) => { + const tableData = JSON.parse(dsl.dsl.children[0].tableData); + cy.get(commonlocators.labelTextStyle).should( + "have.text", + tableData[2].task, + ); + }); + }); + + afterEach(() => { + // put your clean up code if any + }); +}); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/Table_GeneralProperty_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/Table_GeneralProperty_spec.js index 8517c6ba26..8b46421a44 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/Table_GeneralProperty_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/Table_GeneralProperty_spec.js @@ -199,74 +199,4 @@ describe("Table Widget property pane feature validation", function() { cy.get(publish.backToEditor).click(); cy.wait(2000); }); - - it("11. Test to validate text color and text background", function() { - // Open property pane - cy.openPropertyPane("tablewidget"); - // Click on text color input field - cy.get(widgetsPage.textColor) - .first() - .click({ force: true }); - // Select green color - cy.get(widgetsPage.greenColor) - .last() - .click(); - // eslint-disable-next-line cypress/no-unnecessary-waiting - cy.wait(500); - cy.wait("@updateLayout"); - // Verify the text color is green - cy.readTabledataValidateCSS("1", "0", "color", "rgb(3, 179, 101)"); - // Change the text color and enter purple in input field - cy.get(widgetsPage.textColor) - .scrollIntoView() - .clear({ force: true }) - .type("purple", { force: true }); - cy.wait("@updateLayout"); - // Verify the text color is purple - cy.readTabledataValidateCSS("1", "0", "color", "rgb(128, 0, 128)"); - // Click on cell background color - cy.get(`${widgetsPage.cellBackground} input`) - .first() - .scrollIntoView() - .click({ force: true }); - // eslint-disable-next-line cypress/no-unnecessary-waiting - cy.wait(500); - // select the green color - cy.get(widgetsPage.greenColor) - .last() - .click(); - cy.wait("@updateLayout"); - cy.wait(2000); - - cy.PublishtheApp(); - cy.wait(4000); - - // Verify the cell background color is green - cy.readTabledataValidateCSS( - "1", - "1", - "background", - "rgb(3, 179, 101) none repeat scroll 0% 0% / auto padding-box border-box", - ); - cy.get(publish.backToEditor).click(); - cy.openPropertyPane("tablewidget"); - - // Change the cell background color and enter purple in input field - cy.get(`${widgetsPage.cellBackground} input`) - .clear({ force: true }) - .type("purple", { force: true }); - cy.wait("@updateLayout"); - cy.wait(2000); - cy.PublishtheApp(); - cy.wait(4000); - - // Verify the cell background color is purple - cy.readTabledataValidateCSS( - "1", - "1", - "background", - "rgb(128, 0, 128) none repeat scroll 0% 0% / auto padding-box border-box", - ); - cy.get(publish.backToEditor).click(); - }); }); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/Table_Widget_Add_button_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/Table_Widget_Add_button_spec.js index d3bba9248e..d39ecf37b2 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/Table_Widget_Add_button_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/Table_Widget_Add_button_spec.js @@ -208,16 +208,16 @@ describe("Table Widget property pane feature validation", function() { const color1 = "rgb(255, 255, 0)"; cy.get(widgetsPage.menuColor) - .click({ force: true }) .clear() + .click({ force: true }) .type(color1); cy.get(widgetsPage.tableBtn).should("have.css", "background-color", color1); // Changing the color again to reproduce issue #9526 const color2 = "rgb(255, 0, 0)"; cy.get(widgetsPage.menuColor) - .click({ force: true }) .clear() + .click({ force: true }) // following wait is required to reproduce #9526 .wait(500) .type(color2); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/Table_Widget_Copy_Paste_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/Table_Widget_Copy_Paste_spec.js index 01fc32ec0c..a189b47faa 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/Table_Widget_Copy_Paste_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/Table_Widget_Copy_Paste_spec.js @@ -41,7 +41,7 @@ describe("Test Suite to validate copy/paste table Widget", function() { cy.hoverAndClickParticularIndex(1); cy.selectAction("Show Bindings"); cy.get(apiwidget.propertyList).then(function($lis) { - expect($lis).to.have.length(12); + expect($lis).to.have.length(13); expect($lis.eq(0)).to.contain("{{Table1Copy.selectedRow}}"); expect($lis.eq(1)).to.contain("{{Table1Copy.selectedRows}}"); }); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ExplorerTests/Entity_Explorer_Entity_Renaming_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ExplorerTests/Entity_Explorer_Entity_Renaming_spec.js index ec79d81577..1e8acf9016 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ExplorerTests/Entity_Explorer_Entity_Renaming_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ExplorerTests/Entity_Explorer_Entity_Renaming_spec.js @@ -1,9 +1,14 @@ const explorer = require("../../../../locators/explorerlocators.json"); const firstApiName = "First"; const secondApiName = "Second"; +const { + AggregateHelper, +} = require("../../../../support/Pages/AggregateHelper"); + +const helper = new AggregateHelper(); describe("Api Naming conflict on a page test", function() { - it.skip("expects actions on the same page cannot have identical names", function() { + it("expects actions on the same page cannot have identical names", function() { cy.log("Login Successful"); // create an API cy.NavigateToAPI_Panel(); @@ -12,9 +17,11 @@ describe("Api Naming conflict on a page test", function() { // create another API cy.NavigateToAPI_Panel(); cy.CreateAPI(secondApiName); - + helper.expandCollapseEntity("QUERIES/JS", true); // try to rename one of the APIs with an existing API name - cy.hoverAndClickParticularIndex(2); + cy.get(`.t--entity-item:contains(${secondApiName})`).within(() => { + cy.get(".t--context-menu").click({ force: true }); + }); cy.selectAction("Edit Name"); //cy.RenameEntity(tabname); cy.get(explorer.editEntity) @@ -23,8 +30,14 @@ describe("Api Naming conflict on a page test", function() { //cy.RenameEntity(firstApiName); cy.validateMessage(firstApiName); cy.ClearSearch(); - cy.DeleteAPIFromSideBar(); - cy.DeleteAPIFromSideBar(); + cy.get(`.t--entity-item:contains(${secondApiName})`).within(() => { + cy.get(".t--context-menu").click({ force: true }); + }); + cy.deleteActionAndConfirm(); + cy.get(`.t--entity-item:contains(${firstApiName})`).within(() => { + cy.get(".t--context-menu").click({ force: true }); + }); + cy.deleteActionAndConfirm(); }); }); @@ -33,45 +46,65 @@ describe("Api Naming conflict on different pages test", function() { cy.log("Login Successful"); // create a new API cy.CreateAPI(firstApiName); - + helper.expandCollapseEntity("QUERIES/JS", true); // create a new page and an API on that page cy.Createpage("Page2"); cy.CreateAPI(firstApiName); + helper.expandCollapseEntity("QUERIES/JS", true); cy.get(".t--entity-name") .contains(firstApiName) .should("exist"); - cy.DeleteAPIFromSideBar(); - cy.get(".t--entity-name") - .contains("Page2") - .trigger("mouseover"); - cy.hoverAndClick(); - cy.selectAction("Delete"); + cy.get(`.t--entity-item:contains(${firstApiName})`).within(() => { + cy.get(".t--context-menu").click({ force: true }); + }); + cy.deleteActionAndConfirm(); + cy.get(`.t--entity-item:contains(Page2)`).within(() => { + cy.get(".t--context-menu").click({ force: true }); + }); + cy.deleteActionAndConfirm(); + cy.get(`.t--entity-item:contains(${firstApiName})`).within(() => { + cy.get(".t--context-menu").click({ force: true }); + }); + cy.deleteActionAndConfirm(); cy.wait(1000); - cy.DeleteAPIFromSideBar(); }); }); describe("Entity Naming conflict test", function() { it("expects JS objects and actions to not have identical names on the same page.", function() { cy.log("Login Successful"); - + helper.expandCollapseEntity("QUERIES/JS", true); // create JS object and name it cy.createJSObject('return "Hello World";'); - cy.RenameEntity(firstApiName); - // create API and rename it, expect error to occur - cy.NavigateToAPI_Panel(); - cy.CreateAPI(secondApiName); - cy.hoverAndClickParticularIndex(2); + cy.get(`.t--entity-item:contains('JSObject1')`).within(() => { + cy.get(".t--context-menu").click({ force: true }); + }); cy.selectAction("Edit Name"); cy.get(explorer.editEntity) .last() - .type(secondApiName, { force: true }); - cy.VerifyPopOverMessage(secondApiName + " is already being used.", true); - cy.ClearSearch(); + .type(firstApiName, { force: true }); - cy.deleteJSObject(); - cy.DeleteAPIFromSideBar(); - cy.NavigateToHome(); + cy.CreateAPI(secondApiName); + + cy.get(`.t--entity-item:contains(${secondApiName})`).within(() => { + cy.get(".t--context-menu").click({ force: true }); + }); + cy.selectAction("Edit Name"); + + cy.get(explorer.editEntity) + .last() + .type(firstApiName, { force: true }); + cy.VerifyPopOverMessage(firstApiName + " is already being used.", true); + cy.get("body").click(0, 0); + cy.wait(2000); + cy.get(`.t--entity-item:contains(${firstApiName})`).within(() => { + cy.get(".t--context-menu").click({ force: true }); + }); + cy.deleteActionAndConfirm(); + cy.get(`.t--entity-item:contains(${secondApiName})`).within(() => { + cy.get(".t--context-menu").click({ force: true }); + }); + cy.deleteActionAndConfirm(); }); }); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ExplorerTests/Entity_Explorer_Multiple_Widgets_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ExplorerTests/Entity_Explorer_Multiple_Widgets_spec.js index 7b35111737..5f3159166a 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ExplorerTests/Entity_Explorer_Multiple_Widgets_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ExplorerTests/Entity_Explorer_Multiple_Widgets_spec.js @@ -33,19 +33,20 @@ describe("Entity explorer tests related to widgets and validation", function() { .last() .click({ force: true }); cy.get(apiwidget.propertyList).then(function($lis) { - expect($lis).to.have.length(12); + expect($lis).to.have.length(13); expect($lis.eq(0)).to.contain("{{Table1.selectedRow}}"); expect($lis.eq(1)).to.contain("{{Table1.selectedRows}}"); expect($lis.eq(2)).to.contain("{{Table1.selectedRowIndices}}"); expect($lis.eq(3)).to.contain("{{Table1.triggeredRow}}"); expect($lis.eq(4)).to.contain("{{Table1.selectedRowIndex}}"); expect($lis.eq(5)).to.contain("{{Table1.tableData}}"); - expect($lis.eq(6)).to.contain("{{Table1.pageNo}}"); - expect($lis.eq(7)).to.contain("{{Table1.pageSize}}"); - expect($lis.eq(8)).to.contain("{{Table1.isVisible}}"); - expect($lis.eq(9)).to.contain("{{Table1.searchText}}"); - expect($lis.eq(10)).to.contain("{{Table1.totalRecordsCount}}"); - expect($lis.eq(11)).to.contain("{{Table1.sortOrder}}"); + expect($lis.eq(6)).to.contain("{{Table1.filteredTableData}}"); + expect($lis.eq(7)).to.contain("{{Table1.pageNo}}"); + expect($lis.eq(8)).to.contain("{{Table1.pageSize}}"); + expect($lis.eq(9)).to.contain("{{Table1.isVisible}}"); + expect($lis.eq(10)).to.contain("{{Table1.searchText}}"); + expect($lis.eq(11)).to.contain("{{Table1.totalRecordsCount}}"); + expect($lis.eq(12)).to.contain("{{Table1.sortOrder}}"); }); }); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ExplorerTests/Entity_Explorer_Query_Datasource_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ExplorerTests/Entity_Explorer_Query_Datasource_spec.js index becb22ce13..9f54a68721 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ExplorerTests/Entity_Explorer_Query_Datasource_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ExplorerTests/Entity_Explorer_Query_Datasource_spec.js @@ -121,7 +121,9 @@ describe("Entity explorer tests related to query and datasource", function() { .click({ force: true }); cy.contains(".t--datasource-name", datasourceName).click(); cy.get(".t--delete-datasource").click(); - cy.get("[data-cy=t--confirm-modal-btn]").click(); + cy.get(".t--delete-datasource") + .contains("Are you sure?") + .click(); cy.wait("@deleteDatasource").should( "have.nested.property", "response.body.responseMeta.status", diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ExplorerTests/Entity_Explorer_Tab_rename_Delete_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ExplorerTests/Entity_Explorer_Tab_rename_Delete_spec.js index 99f4e38e06..85dbc0ff80 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ExplorerTests/Entity_Explorer_Tab_rename_Delete_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ExplorerTests/Entity_Explorer_Tab_rename_Delete_spec.js @@ -44,7 +44,7 @@ describe("Tab widget test", function() { // eslint-disable-next-line cypress/no-unnecessary-waiting cy.wait(3000); cy.validateMessage(tabname); - cy.deleteEntity(); + cy.deleteEntityWithoutConfirmation(); cy.get(commonlocators.entityExplorersearch) .clear({ force: true }) .type("Tab2", { force: true }); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ExplorerTests/Entity_Explorer_Widgets_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ExplorerTests/Entity_Explorer_Widgets_spec.js index 50af59f024..3e4db10821 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ExplorerTests/Entity_Explorer_Widgets_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/ExplorerTests/Entity_Explorer_Widgets_spec.js @@ -8,7 +8,6 @@ describe("Entity explorer tests related to widgets and validation", function() { }); it("Widget edit/delete/copy to clipboard validation", function() { - cy.wait(30000); cy.CheckAndUnfoldEntityItem("WIDGETS"); cy.selectEntityByName("Container4"); cy.get(".t--entity-collapse-toggle") diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/FormWidgets/ButtonGroup_MenuButton_Width_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/FormWidgets/ButtonGroup_MenuButton_Width_spec.js new file mode 100644 index 0000000000..372f34f163 --- /dev/null +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/FormWidgets/ButtonGroup_MenuButton_Width_spec.js @@ -0,0 +1,148 @@ +const dsl = require("../../../../fixtures/ButtonGroup_MenuButton_Width_dsl.json"); + +const widgetName = "buttongroupwidget"; + +describe("In a button group widget, menu button width", function() { + before(() => { + cy.addDsl(dsl); + }); + + it("If target width is smaller than min-width, The menu button popover width should be set to minimum width", () => { + const minWidth = 12 * 11.9375; + const widgetId = "yxjq5sck7d"; + const menuButtonId = "groupButton3"; + // Get the default menu button + cy.get(`.appsmith_widget_${widgetId} div.t--buttongroup-widget`) + .children() + .last() + .as("target"); + // Open popover + cy.get("@target").click(); + // Get the target width + cy.get("@target") + .invoke("outerWidth") + .then((targetWidth) => { + expect(targetWidth).to.be.lessThan(minWidth); + // Check if popover width is set to its target width + cy.get( + `.bp3-popover2.menu-button-width-${widgetId}-${menuButtonId}`, + ).should("have.css", "width", `${minWidth}px`); + }); + }); + + it("If target width is bigger than min width, The menu button popover width should always be the same as the target width", () => { + const minWidth = 12 * 11.9375; + const widgetId = "t5l24fccio"; + const menuButtonId = "groupButton3"; + + // Get the default menu button + cy.get(`.appsmith_widget_${widgetId} div.t--buttongroup-widget`) + .children() + .last() + .as("target"); + // Open popover + cy.get("@target").click(); + // Get the target width + cy.get("@target") + .invoke("outerWidth") + .then((targetWidth) => { + expect(targetWidth).to.be.greaterThan(minWidth); + // Check if popover width is set to its target width + cy.get( + `.bp3-popover2.menu-button-width-${widgetId}-${menuButtonId}`, + ).should("have.css", "width", `${targetWidth}px`); + }); + }); + + it("After converting a simple button to a menu button, The menu button popover width should always be the same as the target width", () => { + const minWidth = 12 * 11.9375; + const widgetId = "t5l24fccio"; + const menuButtonId = "groupButton1"; + // Change the first button type to menu + cy.editColumn(menuButtonId); + cy.selectDropdownValue(".t--property-control-buttontype", "Menu"); + cy.get(".t--add-menu-item-btn").click(); + // Get the newly converted menu button + cy.get(`.appsmith_widget_${widgetId} div.t--buttongroup-widget`) + .children() + .first() + .as("target"); + // Open popover + cy.get("@target").click(); + // Get the target width + cy.get("@target") + .invoke("outerWidth") + .then((targetWidth) => { + expect(targetWidth).to.be.greaterThan(minWidth); + // Check if popover width is set to its target width + cy.get( + `.bp3-popover2.menu-button-width-${widgetId}-${menuButtonId}`, + ).should("have.css", "width", `${targetWidth}px`); + }); + }); + + it("If an existing menu button width changes, its popover width should always be the same as the changed target width", () => { + const minWidth = 12 * 11.9375; + const widgetId = "t5l24fccio"; + const menuButtonId = "groupButton1"; + cy.get(".t--property-pane-back-btn").click(); + // Change the first button text + cy.get(".t--property-pane-section-buttons input") + .first() + .type("increase width"); + cy.wait("@updateLayout").should( + "have.nested.property", + "response.body.responseMeta.status", + 200, + ); + // Get the menu button with its width changed + cy.get(`.appsmith_widget_${widgetId} div.t--buttongroup-widget`) + .children() + .first() + .as("target"); + // Open popover + cy.get("@target").click(); + // Get the target width + cy.get("@target") + .invoke("outerWidth") + .then((targetWidth) => { + expect(targetWidth).to.be.greaterThan(minWidth); + // Check if popover width is set to its target width + cy.get( + `.bp3-popover2.menu-button-width-${widgetId}-${menuButtonId}`, + ).should("have.css", "width", `${targetWidth}px`); + }); + }); + + it("After changing the orientation to vertical , The menu button popover width should always be the same as the target width", () => { + const widgetId = "mr048y04aq"; + const menuButtonId = "groupButton3"; + // Open property pane of ButtonGroup3 + cy.get(`.appsmith_widget_${widgetId} div.t--buttongroup-widget`) + .children() + .first() + .click(); + // Change its orientation to vetical + cy.selectDropdownValue(".t--property-control-orientation", "Vertical"); + // Get the default menu button + cy.get(`.appsmith_widget_${widgetId} div.t--buttongroup-widget`) + .children() + .last() + .as("target"); + // Open popover + cy.get("@target").click(); + // Get the target width + cy.get("@target") + .invoke("outerWidth") + .then((targetWidth) => { + // Check if popover width is set to its target width + cy.get( + `.bp3-popover2.menu-button-width-${widgetId}-${menuButtonId}`, + ).should("have.css", "width", `${targetWidth}px`); + }); + }); + + after(() => { + // clean up after done + }); +}); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/FormWidgets/ButtonGroup_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/FormWidgets/ButtonGroup_spec.js index 24aa1f1122..6c05582653 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/FormWidgets/ButtonGroup_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/FormWidgets/ButtonGroup_spec.js @@ -1,5 +1,7 @@ const explorer = require("../../../../locators/explorerlocators.json"); +const widgetName = "buttongroupwidget"; + describe("Button Group Widget Functionality", function() { before(() => { // no dsl required diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/FormWidgets/Button_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/FormWidgets/Button_spec.js index 2451cab9d3..83d7f4f526 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/FormWidgets/Button_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/FormWidgets/Button_spec.js @@ -8,6 +8,8 @@ const modalWidgetPage = require("../../../../locators/ModalWidget.json"); const datasource = require("../../../../locators/DatasourcesEditor.json"); const queryLocators = require("../../../../locators/QueryEditor.json"); +const iconAlignmentProperty = ".t--property-control-iconalignment"; + describe("Button Widget Functionality", function() { before(() => { cy.addDsl(dsl); @@ -17,6 +19,52 @@ describe("Button Widget Functionality", function() { cy.openPropertyPane("buttonwidget"); }); + it("Icon alignment should not change when changing the icon", () => { + // Add an icon + cy.get(".t--property-control-icon .bp3-icon-caret-down").click({ + force: true, + }); + + cy.get(".bp3-icon-add") + .first() + .click({ + force: true, + }); + + // Assert if the icon exists + cy.get(`${widgetsPage.buttonWidget} .bp3-icon-add`).should("exist"); + // Change icon alignment to right + cy.get(`${iconAlignmentProperty} .t--button-tab-right`) + .last() + .click({ + force: true, + }); + cy.wait(200); + // Assert if the icon appears on the right hand side of the button text + cy.get(widgetsPage.buttonWidget) + .contains("Submit") + .children("span") + .should("have.length", 2); + cy.get(`${widgetsPage.buttonWidget} span.bp3-button-text`) + .next() + .should("have.class", "bp3-icon-add"); + // Change the existing icon + cy.get(".t--property-control-icon .bp3-icon-caret-down").click({ + force: true, + }); + cy.get(".bp3-icon-airplane") + .first() + .click({ + force: true, + }); + // Assert if the icon changes + // Assert if the icon still exists on the right side of the text + cy.get(`${widgetsPage.buttonWidget} .bp3-icon-airplane`) + .should("exist") + .prev() + .should("have.text", "Submit"); + }); + it("Button-Color Validation", function() { // Change button color cy.changeButtonColor("rgb(255, 0, 0)"); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/FormWidgets/Button_tooltip_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/FormWidgets/Button_tooltip_spec.js index 7ba007900a..b8ebe31f9b 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/FormWidgets/Button_tooltip_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/FormWidgets/Button_tooltip_spec.js @@ -7,30 +7,51 @@ describe("Button Widget Functionality - Validate tooltip visibility", function() cy.addDsl(dsl); }); - it("Validate show tooltip on button hover", function() { + it("Validate show/hide tooltip feature on normal button", function() { cy.openPropertyPane("buttonwidget"); - // add tooltip + // Add tooltip cy.testJsontext( "tooltip", "Lorem Ipsum is simply dummy text of the printing and typesetting industry", ); + // Hover in cy.get(widgetsPage.buttonWidget).trigger("mouseover"); - // tooltip should show on hover + // Check if a tooltip is displayed cy.get(".bp3-popover2-content").should( "have.text", "Lorem Ipsum is simply dummy text of the printing and typesetting industry", ); + // Hover out + cy.get(widgetsPage.buttonWidget).trigger("mouseout"); + // Check if the tooltip is disappeared + cy.get(".bp3-popover2-content") + .contains( + "Lorem Ipsum is simply dummy text of the printing and typesetting industry", + ) + .should("not.exist"); }); - it("Validate tooltip hidden for disabled button", function() { - // first disable button + it("Validate show/hide tooltip feature for a disabled button", function() { + // Disable the button cy.get(".t--property-control-disabled .bp3-switch").click({ force: true }); cy.validateDisableWidget( widgetsPage.buttonWidget, commonlocators.disabledField, ); - // hover on button and check tooltip should not show + // Hover in cy.get(widgetsPage.buttonWidget).trigger("mouseover"); - cy.get(".bp3-popover2-content").should("not.exist"); + // Check if a tooltip is displayed + cy.get(".bp3-popover2-content").should( + "have.text", + "Lorem Ipsum is simply dummy text of the printing and typesetting industry", + ); + // Hover out + cy.get(widgetsPage.buttonWidget).trigger("mouseout"); + // Check if the tooltip is disappeared + cy.get(".bp3-popover2-content") + .contains( + "Lorem Ipsum is simply dummy text of the printing and typesetting industry", + ) + .should("not.exist"); }); }); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/FormWidgets/Inputv2_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/FormWidgets/Inputv2_spec.js index 2b38e4f9ee..12134110ea 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/FormWidgets/Inputv2_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/FormWidgets/Inputv2_spec.js @@ -28,69 +28,315 @@ describe("Input widget V2 - ", () => { cy.get(widgetInput).type("test{enter}"); //Clicking enter submits the form here cy.wait(300); cy.get(widgetInput).should("contain.value", ""); + + cy.selectDropdownValue(".t--property-control-datatype", "Number"); + + cy.get(widgetInput).clear(); + cy.get(widgetInput).type("1.0010{enter}"); //Clicking enter submits the form here + cy.wait(300); + cy.get(widgetInput).should("contain.value", ""); }); it("3. Validate DataType - TEXT can be entered into Input widget", () => { + cy.selectDropdownValue(".t--property-control-datatype", "Text"); [ - "test:test:true", - "test123:test123:true", - "123:123:true", - "::true", - "$100.22:$100.22:true", - "test@appsmith.com:test@appsmith.com:true", - ].forEach((text) => enterAndTest(text.split(":")[0], text)); + { + input: "test", + expected: "test:test:true", + }, + { + input: "test123", + expected: "test123:test123:true", + }, + { + input: "123", + expected: "123:123:true", + }, + { + input: "", + expected: "::true", + }, + { + input: "$100.22", + expected: "$100.22:$100.22:true", + }, + { + input: "test@appsmith.com", + expected: "test@appsmith.com:test@appsmith.com:true", + }, + ].forEach(({ expected, input }) => enterAndTest(input, expected)); cy.openPropertyPane(widgetName); + //required: on cy.get(".t--property-control-required label") .last() .click({ force: true }); [ - "test:test:true", - "test123:test123:true", - "123:123:true", - "-:-:true", - "::false", - "$100.22:$100.22:true", - "test@appsmith.com:test@appsmith.com:true", - ].forEach((text) => enterAndTest(text.split(":")[0], text)); + { + input: "test", + expected: "test:test:true", + }, + { + input: "test123", + expected: "test123:test123:true", + }, + { + input: "123", + expected: "123:123:true", + }, + { + input: "-", + expected: "-:-:true", + }, + { + input: "", + expected: "::false", + }, + { + input: "$100.22", + expected: "$100.22:$100.22:true", + }, + { + input: "test@appsmith.com", + expected: "test@appsmith.com:test@appsmith.com:true", + }, + { + input: "", + expected: "::false", + }, + ].forEach(({ expected, input }) => enterAndTest(input, expected)); }); it("4. Validate DataType - NUMBER can be entered into Input widget", () => { cy.openPropertyPane(widgetName); cy.selectDropdownValue(".t--property-control-datatype", "Number"); [ - "test:", - "test123:123", - "123:123", - "-:-", - ":", - "$100.22:100.22", - "test@appsmith.com:", - ].forEach((text) => { - enterAndTest(text.split(":")[0], text.split(":")[1]); - }); + { + input: "invalid", + expected: "null:null:false", + }, + { + input: "invalid123", + expected: "123:123:true", + }, + { + input: "123", + expected: "123:123:true", + }, + { + input: "-", + expected: "null:null:false", + }, + { + input: "", + expected: "null:null:false", + }, + { + input: "$100.22", + expected: "100.22:100.22:true", + }, + { + input: "invalid@appsmith.com", + expected: "null:null:false", + }, + { + input: "1.001", + expected: "1.001:1.001:true", + }, + { + input: "1.1.", + expected: "null:null:false", + }, + ].forEach(({ expected, input }) => enterAndTest(input, expected)); + + //required: off + cy.get(".t--property-control-required label") + .last() + .click({ force: true }); + + cy.selectDropdownValue(".t--property-control-datatype", "Number"); + [ + { + input: "invalid", + expected: "null:null:true", + }, + { + input: "invalid123", + expected: "123:123:true", + }, + { + input: "123", + expected: "123:123:true", + }, + { + input: "-", + expected: "null:null:false", + }, + { + input: "", + expected: "null:null:true", + }, + { + input: "$100.22", + expected: "100.22:100.22:true", + }, + { + input: "invalid@appsmith.com", + expected: "null:null:false", + }, + { + input: "1.001", + expected: "1.001:1.001:true", + }, + { + input: "1.1.", + expected: "null:null:false", + }, + ].forEach(({ expected, input }) => enterAndTest(input, expected)); }); it("5. Validate DataType - PASSWORD can be entered into Input widget", () => { cy.openPropertyPane(widgetName); cy.selectDropdownValue(".t--property-control-datatype", "Password"); - ["test", "test123", "123", "-", "", "$100.22", "test@appsmith.com"].forEach( - (text) => { - enterAndTest(text, text); + [ + { + input: "test", + expected: "test:test:true", }, - ); + { + input: "test123", + expected: "test123:test123:true", + }, + { + input: "123", + expected: "123:123:true", + }, + { + input: "-", + expected: "-:-:true", + }, + { + input: "", + expected: "::true", + }, + { + input: "$100.22", + expected: "$100.22:$100.22:true", + }, + { + input: "test@appsmith.com", + expected: "test@appsmith.com:test@appsmith.com:true", + }, + ].forEach(({ expected, input }) => enterAndTest(input, expected)); + + //required: on + cy.get(".t--property-control-required label") + .last() + .click({ force: true }); + + [ + { + input: "test", + expected: "test:test:true", + }, + { + input: "test123", + expected: "test123:test123:true", + }, + { + input: "123", + expected: "123:123:true", + }, + { + input: "-", + expected: "-:-:true", + }, + { + input: "", + expected: "::false", + }, + { + input: "$100.22", + expected: "$100.22:$100.22:true", + }, + { + input: "test@appsmith.com", + expected: "test@appsmith.com:test@appsmith.com:true", + }, + ].forEach(({ expected, input }) => enterAndTest(input, expected)); }); it("6. Validate DataType - EMAIL can be entered into Input widget", () => { cy.openPropertyPane(widgetName); cy.selectDropdownValue(".t--property-control-datatype", "Email"); - ["test", "test123", "123", "-", "", "$100.22", "test@appsmith.com"].forEach( - (text) => { - enterAndTest(text, text); + [ + { + input: "test", + expected: "test:test:false", }, - ); + { + input: "test123", + expected: "test123:test123:false", + }, + { + input: "123", + expected: "123:123:false", + }, + { + input: "-", + expected: "-:-:false", + }, + { + input: "", + expected: "::false", + }, + { + input: "$100.22", + expected: "$100.22:$100.22:false", + }, + { + input: "test@appsmith.com", + expected: "test@appsmith.com:test@appsmith.com:true", + }, + ].forEach(({ expected, input }) => enterAndTest(input, expected)); + + //required: off + cy.get(".t--property-control-required label") + .last() + .click({ force: true }); + + [ + { + input: "test", + expected: "test:test:false", + }, + { + input: "test123", + expected: "test123:test123:false", + }, + { + input: "123", + expected: "123:123:false", + }, + { + input: "-", + expected: "-:-:false", + }, + { + input: "", + expected: "::true", + }, + { + input: "$100.22", + expected: "$100.22:$100.22:false", + }, + { + input: "test@appsmith.com", + expected: "test@appsmith.com:test@appsmith.com:true", + }, + ].forEach(({ expected, input }) => enterAndTest(input, expected)); }); it("7. Validating other properties - Input validity with #valid", () => { @@ -107,13 +353,82 @@ describe("Input widget V2 - ", () => { }); }); + it("8. onSubmit should be triggered with the whole input value", () => { + cy.openPropertyPane(widgetName); + cy.selectDropdownValue(".t--property-control-datatype", "Text"); + cy.get(".t--property-control-required label") + .last() + .click({ force: true }); + // Set onSubmit action, storing value + cy.get(".t--property-control-onsubmit") + .find(".t--js-toggle") + .click(); + cy.updateCodeInput( + ".t--property-control-onsubmit", + "{{storeValue('textPayloadOnSubmit',Input1.text)}}", + ); + // Bind to stored value above + cy.openPropertyPane("textwidget"); + cy.updateCodeInput( + ".t--property-control-text", + "{{appsmith.store.textPayloadOnSubmit}}", + ); + cy.closePropertyPane(); + cy.get(widgetInput).clear(); + cy.wait(300); + // Input text and hit enter key + cy.get(widgetInput).type("test{enter}"); + // Assert if the Text widget contains the whole value, test + cy.get(".t--widget-textwidget").should("have.text", "test"); + }); + + it("9. changing default text should change text", () => { + cy.openPropertyPane("textwidget"); + cy.updateCodeInput( + ".t--property-control-text", + `{{Input1.text}}:{{Input1.value}}:{{Input1.isValid}}`, + ); + cy.openPropertyPane(widgetName); + cy.updateCodeInput(".t--property-control-defaulttext", `test`); + // wait for evaluations + cy.wait(300); + cy.get(`.t--widget-${widgetName} input`).should("contain.value", "test"); + cy.get(".t--widget-textwidget").should("contain", "test:test:true"); + + cy.updateCodeInput(".t--property-control-defaulttext", `anotherText`); + // wait for evaluations + cy.wait(300); + cy.get(`.t--widget-${widgetName} input`).should( + "contain.value", + "anotherText", + ); + cy.get(".t--widget-textwidget").should( + "contain", + "anotherText:anotherText:true", + ); + + cy.selectDropdownValue(".t--property-control-datatype", "Number"); + + cy.updateCodeInput(".t--property-control-defaulttext", `{{1}}`); + // wait for evaluations + cy.wait(300); + cy.get(`.t--widget-${widgetName} input`).should("contain.value", "1"); + cy.get(".t--widget-textwidget").should("contain", "1:1:true"); + + cy.updateCodeInput(".t--property-control-defaulttext", `{{1.00010000}}`); + // wait for evaluations + cy.wait(300); + cy.get(`.t--widget-${widgetName} input`).should("contain.value", "1.0001"); + cy.get(".t--widget-textwidget").should("contain", "1.0001:1.0001:true"); + }); + function enterAndTest(text, expected) { cy.get(`.t--widget-${widgetName} input`).clear(); cy.wait(300); if (text) { cy.get(`.t--widget-${widgetName} input`) .click() - .type(text); //.should('have.value', text); + .type(text); } cy.get(".t--widget-textwidget").should("contain", expected); } diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/FormWidgets/JSONFormWidget/JSONForm_ArrayField_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/FormWidgets/JSONFormWidget/JSONForm_ArrayField_spec.js new file mode 100644 index 0000000000..228e0be644 --- /dev/null +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/FormWidgets/JSONFormWidget/JSONForm_ArrayField_spec.js @@ -0,0 +1,143 @@ +const commonlocators = require("../../../../../locators/commonlocators.json"); +const dslWithSchema = require("../../../../../fixtures/jsonFormDslWithSchema.json"); + +const fieldPrefix = ".t--jsonformfield"; +const education = `${fieldPrefix}-education`; +const addButton = ".t--jsonformfield-array-add-btn"; +const deleteButton = ".t--jsonformfield-array-delete-btn"; + +describe("JSON Form Widget Array Field", () => { + before(() => { + cy.addDsl(dslWithSchema); + }); + + it("can add more items to the field", () => { + cy.openPropertyPane("jsonformwidget"); + + cy.get(`${education}-item`) + .should("have.length", 1) + .within(() => { + cy.get(`${education}-0--college input`).should("have.value", "MIT"); + cy.get(`${education}-0--year input`).should("have.value", "20/10/2014"); + }); + + cy.get(`${education} ${addButton}`).click({ force: true }); + + cy.get(`${education}-item`) + .should("have.length", 2) + .within(() => { + cy.get(`${education}-0--college input`).should("have.value", "MIT"); + cy.get(`${education}-0--year input`).should("have.value", "20/10/2014"); + cy.get(`${education}-1--college input`).should("have.value", ""); + cy.get(`${education}-1--year input`).should("have.value", ""); + }); + }); + + it("can remove items from the field", () => { + cy.get(`${education} ${addButton}`).click({ force: true }); + cy.get(`${education}-item`).should("have.length", 3); + + cy.get(`${education}-item`).within(() => { + cy.get(`${education}-1--college input`).type("Dummy college"); + cy.get(`${education}-1--year input`).type("10/08/2010"); + }); + + cy.get(commonlocators.canvas).click({ force: true }); + + cy.get(`${education}-item`).within(() => { + cy.get(`${education}-2--college input`).type("Dummy college 2"); + cy.get(`${education}-2--year input`).type("01/01/2020"); + }); + + cy.get(commonlocators.canvas).click({ force: true }); + + cy.get(`${education}-item.t--item-1`) + .find(deleteButton) + .click({ force: true }); + + cy.get(`${education}-item`).should("have.length", 2); + + cy.get(`${education}-item`).within(() => { + cy.get(`${education}-1--college input`).should( + "have.value", + "Dummy college 2", + ); + cy.get(`${education}-1--year input`).should("have.value", "01/01/2020"); + }); + }); + + it("can change the visibility of the field", () => { + cy.get(education).should("exist"); + + cy.openPropertyPane("jsonformwidget"); + cy.openFieldConfiguration("education"); + + // Visible -> false + cy.togglebarDisable(".t--property-control-visible input"); + cy.get(education).should("not.exist"); + + // Visible -> true + cy.togglebar(".t--property-control-visible input"); + cy.get(education).should("exist"); + }); + + it("disables all underlying field when array field is disabled", () => { + cy.closePropertyPane(); + cy.openPropertyPane("jsonformwidget"); + cy.openFieldConfiguration("education"); + + // Disable -> true + cy.togglebar(".t--property-control-disabled input"); + cy.get(education).within(() => { + cy.get(`${education}-0--college input`).should("have.attr", "disabled"); + cy.get(`${education}-0--year input`).should("have.attr", "disabled"); + }); + + // Disable -> false + cy.togglebarDisable(".t--property-control-disabled input"); + cy.get(education).should("exist"); + cy.get(education).within(() => { + cy.get(`${education}-0--college input`).should( + "not.have.attr", + "disabled", + ); + cy.get(`${education}-0--year input`).should("not.have.attr", "disabled"); + }); + }); + + it("should not render field level default value if form level is present", () => { + const collegeFieldDefaultValue = "College default value"; + + cy.closePropertyPane(); + cy.openPropertyPane("jsonformwidget"); + + cy.openFieldConfiguration("education") + .openFieldConfiguration("__array_item__") + .openFieldConfiguration("college"); + + // Modify default text of eductation -> college field + cy.testJsontext("defaultvalue", collegeFieldDefaultValue); + cy.closePropertyPane(); + cy.get(`${education}-item`) + .should("have.length", 1) + .within(() => { + cy.get(`${education}-0--college input`).should("have.value", "MIT"); + cy.get(`${education}-0--year input`).should("have.value", "20/10/2014"); + }); + + // Add new item to education array + cy.get(`${education} ${addButton}`).click({ force: true }); + + cy.get(`${education}-item`) + .should("have.length", 2) + .within(() => { + cy.get(`${education}-0--college input`).should("have.value", "MIT"); + cy.get(`${education}-0--year input`).should("have.value", "20/10/2014"); + cy.get(`${education}-1--college input`).should( + "have.value", + collegeFieldDefaultValue, + ); + cy.get(`${education}-1--year input`).should("have.value", ""); + }); + }); +}); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/FormWidgets/JSONFormWidget/JSONForm_AutoGenerateFormDisabled_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/FormWidgets/JSONFormWidget/JSONForm_AutoGenerateFormDisabled_spec.js new file mode 100644 index 0000000000..b46c6b15fc --- /dev/null +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/FormWidgets/JSONFormWidget/JSONForm_AutoGenerateFormDisabled_spec.js @@ -0,0 +1,220 @@ +const jsonFormDslWithSchemaAndWithoutSourceData = require("../../../../../fixtures/jsonFormDslWithSchemaAndWithoutSourceData.json"); + +const fieldPrefix = ".t--jsonformfield"; + +describe("JSON Form Widget AutoGenerate Disabled", () => { + it("generates fields with valid source data json", () => { + const formDsl = JSON.parse( + JSON.stringify(jsonFormDslWithSchemaAndWithoutSourceData), + ); + + cy.addDsl(formDsl); + + cy.openPropertyPane("jsonformwidget"); + + cy.togglebarDisable(`.t--property-control-autogenerateform input`); + + const sourceData = { + name: "John", + age: 30, + dob: "10/12/1992", + migrant: false, + gender: "male", + address: { + street: "Koramangala", + city: "Bangalore", + state: "State", + }, + education: [ + { + college: "MIT", + year: "20/10/2014", + course: "CS", + }, + ], + }; + + cy.openPropertyPane("jsonformwidget"); + cy.testJsontext("sourcedata", JSON.stringify(sourceData)); + cy.closePropertyPane(); + + // Fields that should exist + cy.get(`${fieldPrefix}-name label`).contains("Name"); + cy.get(`${fieldPrefix}-name input`).then((input) => { + cy.wrap(input).should("have.value", "John"); + cy.wrap(input) + .invoke("attr", "type") + .should("contain", "text"); + }); + + cy.get(`${fieldPrefix}-age label`).contains("Age"); + cy.get(`${fieldPrefix}-age input`).then((input) => { + cy.wrap(input).should("have.value", 30); + cy.wrap(input) + .invoke("attr", "type") + .should("contain", "text"); + }); + + cy.get(`${fieldPrefix}-dob label`).contains("Dob"); + cy.get(`${fieldPrefix}-dob input`).then((input) => { + cy.wrap(input).should("have.value", "10/12/1992"); + cy.wrap(input) + .invoke("attr", "type") + .should("contain", "text"); + }); + + cy.get(`${fieldPrefix}-migrant label`).contains("Migrant"); + cy.get(`${fieldPrefix}-migrant .t--switch-widget-inactive`).should("exist"); + + cy.get(`${fieldPrefix}-address`) + .find("label") + .should("have.length", 3); + cy.get(`${fieldPrefix}-address-street label`).contains("Street"); + cy.get(`${fieldPrefix}-address-street input`).then((input) => { + cy.wrap(input).should("have.value", "Koramangala"); + cy.wrap(input) + .invoke("attr", "type") + .should("contain", "text"); + }); + + cy.get(`${fieldPrefix}-address-city label`).contains("City"); + cy.get(`${fieldPrefix}-address-city input`).then((input) => { + cy.wrap(input).should("have.value", "Bangalore"); + cy.wrap(input) + .invoke("attr", "type") + .should("contain", "text"); + }); + + cy.get(`${fieldPrefix}-education label`).should("have.length", 3); + + cy.get(`${fieldPrefix}-education-0--college label`).contains("College"); + cy.get(`${fieldPrefix}-education-0--college input`).then((input) => { + cy.wrap(input).should("have.value", "MIT"); + cy.wrap(input) + .invoke("attr", "type") + .should("contain", "text"); + }); + + cy.get(`${fieldPrefix}-education-0--year label`).contains("Year"); + cy.get(`${fieldPrefix}-education-0--year input`).then((input) => { + cy.wrap(input).should("have.value", "20/10/2014"); + cy.wrap(input) + .invoke("attr", "type") + .should("contain", "text"); + }); + + cy.get( + `${fieldPrefix}-education .t--jsonformfield-array-delete-btn .t--text`, + ).should("have.text", "Delete"); + cy.get( + `${fieldPrefix}-education .t--jsonformfield-array-add-btn .t--text`, + ).should("have.text", "Add New"); + + /** + * Fields that shouldn't exist + * */ + cy.get(`${fieldPrefix}-gender label`).should("not.exist"); + cy.get(`${fieldPrefix}-gender input`).should("not.exist"); + + cy.get(`${fieldPrefix}-address-state label`).should("not.exist"); + cy.get(`${fieldPrefix}-address-state input`).should("not.exist"); + + cy.get(`${fieldPrefix}-education-0--course label`).should("not.exist"); + cy.get(`${fieldPrefix}-education-0--course input`).should("not.exist"); + }); + + it("modifies field when generate form button is pressed", () => { + const formDsl = JSON.parse( + JSON.stringify(jsonFormDslWithSchemaAndWithoutSourceData), + ); + + cy.addDsl(formDsl); + + cy.openPropertyPane("jsonformwidget"); + + cy.togglebarDisable(`.t--property-control-autogenerateform input`); + + const sourceData = { + name: "John", + age: 30, + dob: "10/12/1992", + migrant: false, + gender: "male", + address: { + street: "Koramangala", + city: "Bangalore", + state: "Karnataka", + }, + education: [ + { + college: "MIT", + year: "20/10/2014", + course: "CS", + }, + ], + }; + + cy.openPropertyPane("jsonformwidget"); + cy.testJsontext("sourcedata", JSON.stringify(sourceData)); + + cy.wait(500); + + cy.get(".t--property-pane-section-general button") + .contains("Generate Form") + .click({ force: true }); + cy.closePropertyPane(); + + cy.get(`${fieldPrefix}-name label`).contains("Name"); + cy.get(`${fieldPrefix}-name input`).should("have.value", "John"); + + cy.get(`${fieldPrefix}-age label`).contains("Age"); + cy.get(`${fieldPrefix}-age input`).should("have.value", 30); + + cy.get(`${fieldPrefix}-dob label`).contains("Dob"); + cy.get(`${fieldPrefix}-dob input`).should("have.value", "10/12/1992"); + + cy.get(`${fieldPrefix}-migrant label`).contains("Migrant"); + cy.get(`${fieldPrefix}-migrant .t--switch-widget-inactive`).should("exist"); + + cy.get(`${fieldPrefix}-address`) + .find("label") + .should("have.length", 4); + cy.get(`${fieldPrefix}-address-street label`).contains("Street"); + cy.get(`${fieldPrefix}-address-street input`).should( + "have.value", + "Koramangala", + ); + + cy.get(`${fieldPrefix}-address-city label`).contains("City"); + cy.get(`${fieldPrefix}-address-city input`).should( + "have.value", + "Bangalore", + ); + + cy.get(`${fieldPrefix}-address-state label`).contains("State"); + cy.get(`${fieldPrefix}-address-state input`).should( + "have.value", + "Karnataka", + ); + + cy.get(`${fieldPrefix}-education label`).should("have.length", 4); + + cy.get(`${fieldPrefix}-education-0--college label`).contains("College"); + cy.get(`${fieldPrefix}-education-0--college input`).should( + "have.value", + "MIT", + ); + + cy.get(`${fieldPrefix}-education-0--year label`).contains("Year"); + cy.get(`${fieldPrefix}-education-0--year input`).should( + "have.value", + "20/10/2014", + ); + + cy.get(`${fieldPrefix}-education-0--course label`).contains("Course"); + cy.get(`${fieldPrefix}-education-0--course input`).should( + "have.value", + "CS", + ); + }); +}); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/FormWidgets/JSONFormWidget/JSONForm_AutoGenerateFormEnabled_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/FormWidgets/JSONFormWidget/JSONForm_AutoGenerateFormEnabled_spec.js new file mode 100644 index 0000000000..21e883e5bd --- /dev/null +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/FormWidgets/JSONFormWidget/JSONForm_AutoGenerateFormEnabled_spec.js @@ -0,0 +1,184 @@ +const dslWithoutSchema = require("../../../../../fixtures/jsonFormDslWithoutSchema.json"); +const jsonFormDslWithSchemaAndWithoutSourceData = require("../../../../../fixtures/jsonFormDslWithSchemaAndWithoutSourceData.json"); + +const fieldPrefix = ".t--jsonformfield"; + +describe("JSON Form Widget AutoGenerate Enabled", () => { + it("generates fields with valid source data json", () => { + cy.addDsl(dslWithoutSchema); + const sourceData = { + name: "John", + age: 30, + dob: "10/12/1992", + migrant: false, + address: { + street: "Koramangala", + city: "Bangalore", + }, + education: [ + { + college: "MIT", + year: "20/10/2014", + }, + ], + }; + + cy.openPropertyPane("jsonformwidget"); + cy.testJsontext("sourcedata", JSON.stringify(sourceData)); + cy.closePropertyPane(); + + cy.get(`${fieldPrefix}-name label`).contains("Name"); + cy.get(`${fieldPrefix}-name input`).then((input) => { + cy.wrap(input).should("have.value", "John"); + cy.wrap(input) + .invoke("attr", "type") + .should("contain", "text"); + }); + + cy.get(`${fieldPrefix}-age label`).contains("Age"); + cy.get(`${fieldPrefix}-age input`).then((input) => { + cy.wrap(input).should("have.value", 30); + cy.wrap(input) + .invoke("attr", "type") + .should("contain", "text"); + }); + + cy.get(`${fieldPrefix}-dob label`).contains("Dob"); + cy.get(`${fieldPrefix}-dob input`).then((input) => { + cy.wrap(input).should("have.value", "10/12/1992"); + cy.wrap(input) + .invoke("attr", "type") + .should("contain", "text"); + }); + + cy.get(`${fieldPrefix}-migrant label`).contains("Migrant"); + cy.get(`${fieldPrefix}-migrant .t--switch-widget-inactive`).should("exist"); + + cy.get(`${fieldPrefix}-address`) + .find("label") + .should("have.length", 3); + cy.get(`${fieldPrefix}-address-street label`).contains("Street"); + cy.get(`${fieldPrefix}-address-street input`).then((input) => { + cy.wrap(input).should("have.value", "Koramangala"); + cy.wrap(input) + .invoke("attr", "type") + .should("contain", "text"); + }); + + cy.get(`${fieldPrefix}-address-city label`).contains("City"); + cy.get(`${fieldPrefix}-address-city input`).then((input) => { + cy.wrap(input).should("have.value", "Bangalore"); + cy.wrap(input) + .invoke("attr", "type") + .should("contain", "text"); + }); + + cy.get(`${fieldPrefix}-education label`).should("have.length", 3); + + cy.get(`${fieldPrefix}-education-0--college label`).contains("College"); + cy.get(`${fieldPrefix}-education-0--college input`).then((input) => { + cy.wrap(input).should("have.value", "MIT"); + cy.wrap(input) + .invoke("attr", "type") + .should("contain", "text"); + }); + + cy.get(`${fieldPrefix}-education-0--year label`).contains("Year"); + cy.get(`${fieldPrefix}-education-0--year input`).then((input) => { + cy.wrap(input).should("have.value", "20/10/2014"); + cy.wrap(input) + .invoke("attr", "type") + .should("contain", "text"); + }); + + cy.get( + `${fieldPrefix}-education .t--jsonformfield-array-delete-btn .t--text`, + ).should("have.text", "Delete"); + cy.get( + `${fieldPrefix}-education .t--jsonformfield-array-add-btn .t--text`, + ).should("have.text", "Add New"); + }); + + it("modifies field when source data changes", () => { + cy.addDsl(jsonFormDslWithSchemaAndWithoutSourceData); + + const modifiedSourceData = { + name: "John", + age: 30, + dob: "10/12/1992", + migrant: "false", + address: { + street: "Koramangala", + city: "Bangalore", + state: "Karnataka", + }, + education: [ + { + college: "MIT", + year: "20/10/2014", + degree: "Engg.", + }, + ], + }; + + cy.openPropertyPane("jsonformwidget"); + cy.testJsontext("sourcedata", JSON.stringify(modifiedSourceData)); + cy.closePropertyPane(); + + cy.get(`${fieldPrefix}-name label`).contains("Name"); + cy.get(`${fieldPrefix}-name input`).should("have.value", "John"); + + cy.get(`${fieldPrefix}-age label`).contains("Age"); + cy.get(`${fieldPrefix}-age input`).should("have.value", 30); + + cy.get(`${fieldPrefix}-dob label`).contains("Dob"); + cy.get(`${fieldPrefix}-dob input`).should("have.value", "10/12/1992"); + + cy.get(`${fieldPrefix}-migrant label`).contains("Migrant"); + cy.get(`${fieldPrefix}-migrant .t--switch-widget-inactive`).should( + "not.exist", + ); + cy.get(`${fieldPrefix}-migrant input`).should("exist"); + + cy.get(`${fieldPrefix}-address`) + .find("label") + .should("have.length", 4); + cy.get(`${fieldPrefix}-address-street label`).contains("Street"); + cy.get(`${fieldPrefix}-address-street input`).should( + "have.value", + "Koramangala", + ); + + cy.get(`${fieldPrefix}-address-city label`).contains("City"); + cy.get(`${fieldPrefix}-address-city input`).should( + "have.value", + "Bangalore", + ); + + cy.get(`${fieldPrefix}-address-state label`).contains("State"); + cy.get(`${fieldPrefix}-address-state input`).should( + "have.value", + "Karnataka", + ); + + cy.get(`${fieldPrefix}-education label`).should("have.length", 4); + + cy.get(`${fieldPrefix}-education-0--college label`).contains("College"); + cy.get(`${fieldPrefix}-education-0--college input`).should( + "have.value", + "MIT", + ); + + cy.get(`${fieldPrefix}-education-0--year label`).contains("Year"); + cy.get(`${fieldPrefix}-education-0--year input`).should( + "have.value", + "20/10/2014", + ); + + cy.get(`${fieldPrefix}-education-0--degree label`).contains("Degree"); + cy.get(`${fieldPrefix}-education-0--degree input`).should( + "have.value", + "Engg.", + ); + }); +}); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/FormWidgets/JSONFormWidget/JSONForm_CustomField_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/FormWidgets/JSONFormWidget/JSONForm_CustomField_spec.js new file mode 100644 index 0000000000..ab133a1e20 --- /dev/null +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/FormWidgets/JSONFormWidget/JSONForm_CustomField_spec.js @@ -0,0 +1,109 @@ +const commonlocators = require("../../../../../locators/commonlocators.json"); +const jsonFormDslWithSchemaAndWithoutSourceData = require("../../../../../fixtures/jsonFormDslWithSchemaAndWithoutSourceData.json"); + +const fieldPrefix = ".t--jsonformfield"; + +describe("JSON Form Widget Custom Field", () => { + it("uses the custom field when the accessor matches", () => { + const formDsl = JSON.parse( + JSON.stringify(jsonFormDslWithSchemaAndWithoutSourceData), + ); + + cy.addDsl(formDsl); + + cy.openPropertyPane("jsonformwidget"); + + // Add new custom field + cy.get(".t--property-pane-section-general button") + .contains("Add a new field") + .click({ force: true }); + + cy.openFieldConfiguration("customField1"); + + cy.testJsontext("propertyname", "gender"); + cy.testJsontext("label", "Gender"); + cy.selectDropdownValue(commonlocators.jsonFormFieldType, "Select"); + cy.closePropertyPane(); + + const sourceData = { + name: "John", + age: 30, + dob: "10/12/1992", + migrant: false, + gender: "male", + address: { + street: "Koramangala", + city: "Bangalore", + state: "Karnataka", + }, + education: [ + { + college: "MIT", + year: "20/10/2014", + course: "CS", + }, + ], + }; + + cy.openPropertyPane("jsonformwidget"); + cy.testJsontext("sourcedata", JSON.stringify(sourceData)); + + cy.wait(500); + + cy.get(`${fieldPrefix}-name label`).contains("Name"); + cy.get(`${fieldPrefix}-name input`).should("have.value", "John"); + + cy.get(`${fieldPrefix}-age label`).contains("Age"); + cy.get(`${fieldPrefix}-age input`).should("have.value", 30); + + cy.get(`${fieldPrefix}-dob label`).contains("Dob"); + cy.get(`${fieldPrefix}-dob input`).should("have.value", "10/12/1992"); + + cy.get(`${fieldPrefix}-customField1 label`).contains("Gender"); + cy.get(`${fieldPrefix}-customField1 .bp3-popover-wrapper`).should("exist"); + + cy.get(`${fieldPrefix}-migrant label`).contains("Migrant"); + cy.get(`${fieldPrefix}-migrant .t--switch-widget-inactive`).should("exist"); + + cy.get(`${fieldPrefix}-address`) + .find("label") + .should("have.length", 4); + cy.get(`${fieldPrefix}-address-street label`).contains("Street"); + cy.get(`${fieldPrefix}-address-street input`).should( + "have.value", + "Koramangala", + ); + + cy.get(`${fieldPrefix}-address-city label`).contains("City"); + cy.get(`${fieldPrefix}-address-city input`).should( + "have.value", + "Bangalore", + ); + + cy.get(`${fieldPrefix}-address-state label`).contains("State"); + cy.get(`${fieldPrefix}-address-state input`).should( + "have.value", + "Karnataka", + ); + + cy.get(`${fieldPrefix}-education label`).should("have.length", 4); + + cy.get(`${fieldPrefix}-education-0--college label`).contains("College"); + cy.get(`${fieldPrefix}-education-0--college input`).should( + "have.value", + "MIT", + ); + + cy.get(`${fieldPrefix}-education-0--year label`).contains("Year"); + cy.get(`${fieldPrefix}-education-0--year input`).should( + "have.value", + "20/10/2014", + ); + + cy.get(`${fieldPrefix}-education-0--course label`).contains("Course"); + cy.get(`${fieldPrefix}-education-0--course input`).should( + "have.value", + "CS", + ); + }); +}); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/FormWidgets/JSONFormWidget/JSONForm_FieldChange_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/FormWidgets/JSONFormWidget/JSONForm_FieldChange_spec.js new file mode 100644 index 0000000000..5f11de06e3 --- /dev/null +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/FormWidgets/JSONFormWidget/JSONForm_FieldChange_spec.js @@ -0,0 +1,191 @@ +const commonlocators = require("../../../../../locators/commonlocators.json"); +const dslWithSchema = require("../../../../../fixtures/jsonFormDslWithSchema.json"); + +const fieldPrefix = ".t--jsonformfield"; + +describe("JSON Form Widget Field Change", () => { + before(() => { + cy.addDsl(dslWithSchema); + }); + + it("modifies field type text to number", () => { + cy.openPropertyPane("jsonformwidget"); + + cy.get(`${fieldPrefix}-name`) + .find("button") + .should("not.exist"); + cy.openFieldConfiguration("name"); + cy.selectDropdownValue(commonlocators.jsonFormFieldType, "Number Input"); + cy.get(`${fieldPrefix}-name`) + .find("button") + .should("have.length", 2); + cy.selectDropdownValue(commonlocators.jsonFormFieldType, /^Text Input$/); + cy.closePropertyPane(); + }); + + it("modifies field type text to checkbox", () => { + cy.openPropertyPane("jsonformwidget"); + + cy.get(`${fieldPrefix}-name`) + .find("input") + .invoke("attr", "type") + .should("contain", "text"); + cy.openFieldConfiguration("name"); + cy.selectDropdownValue(commonlocators.jsonFormFieldType, "Checkbox"); + cy.get(`${fieldPrefix}-name`) + .find("input") + .invoke("attr", "type") + .should("contain", "checkbox"); + cy.selectDropdownValue(commonlocators.jsonFormFieldType, /^Text Input$/); + cy.closePropertyPane(); + }); + + it("modifies field type text to date", () => { + cy.openPropertyPane("jsonformwidget"); + + cy.get(`${fieldPrefix}-name`) + .find("input") + .click({ force: true }); + cy.get(".bp3-popover.bp3-dateinput-popover").should("not.exist"); + cy.openFieldConfiguration("name"); + cy.selectDropdownValue(commonlocators.jsonFormFieldType, "Datepicker"); + cy.get(`${fieldPrefix}-name`) + .find("input") + .click({ force: true }); + cy.get(".bp3-popover.bp3-dateinput-popover").should("exist"); + cy.selectDropdownValue(commonlocators.jsonFormFieldType, /^Text Input$/); + cy.closePropertyPane(); + }); + + it("modifies field type text to switch", () => { + cy.openPropertyPane("jsonformwidget"); + + cy.get(`${fieldPrefix}-name`) + .find(".bp3-control.bp3-switch") + .should("not.exist"); + + cy.openFieldConfiguration("name"); + cy.selectDropdownValue(commonlocators.jsonFormFieldType, "Switch"); + + cy.get(`${fieldPrefix}-name`) + .find(".bp3-control.bp3-switch") + .should("exist"); + + cy.selectDropdownValue(commonlocators.jsonFormFieldType, /^Text Input$/); + cy.closePropertyPane(); + }); + + it("modifies field type text to Select", () => { + cy.openPropertyPane("jsonformwidget"); + + cy.get(`${fieldPrefix}-name label`).click({ force: true }); + cy.get(".bp3-select-popover.select-popover-wrapper").should("not.exist"); + + cy.openFieldConfiguration("name"); + cy.selectDropdownValue(commonlocators.jsonFormFieldType, /^Select$/); + + cy.get(`${fieldPrefix}-name label`).click({ force: true }); + cy.get(".bp3-select-popover.select-popover-wrapper").should("exist"); + + cy.selectDropdownValue(commonlocators.jsonFormFieldType, /^Text Input$/); + cy.closePropertyPane(); + }); + + it("modifies field type text to Multi-Select", () => { + cy.openPropertyPane("jsonformwidget"); + + cy.get(`${fieldPrefix}-name`) + .find(".rc-select-multiple") + .should("not.exist"); + + cy.openFieldConfiguration("name"); + cy.selectDropdownValue(commonlocators.jsonFormFieldType, "Multiselect"); + cy.get(`${fieldPrefix}-name`) + .find(".rc-select-multiple") + .should("exist"); + + cy.selectDropdownValue(commonlocators.jsonFormFieldType, /^Text Input$/); + cy.closePropertyPane(); + }); + + it("modifies field type text to Radio-Group", () => { + cy.openPropertyPane("jsonformwidget"); + + cy.get(`${fieldPrefix}-name`) + .find(".bp3-control.bp3-radio") + .should("not.exist"); + + cy.openFieldConfiguration("name"); + cy.selectDropdownValue(commonlocators.jsonFormFieldType, "Radio Group"); + cy.get(`${fieldPrefix}-name`) + .find(".bp3-control.bp3-radio") + .should("exist") + .should("have.length", 2); + + cy.selectDropdownValue(commonlocators.jsonFormFieldType, /^Text Input$/); + cy.closePropertyPane(); + }); + + it("modifies field type text to Array", () => { + cy.openPropertyPane("jsonformwidget"); + + cy.get(`${fieldPrefix}-name`) + .find(".t--jsonformfield-array-add-btn") + .should("not.exist"); + + cy.openFieldConfiguration("name"); + cy.selectDropdownValue(commonlocators.jsonFormFieldType, "Array"); + cy.get(`${fieldPrefix}-name`) + .find(".t--jsonformfield-array-add-btn") + .should("exist"); + + cy.selectDropdownValue(commonlocators.jsonFormFieldType, /^Text Input$/); + cy.closePropertyPane(); + }); + + it("modifies field type text to Object", () => { + cy.openPropertyPane("jsonformwidget"); + + cy.openFieldConfiguration("name"); + cy.selectDropdownValue(commonlocators.jsonFormFieldType, "Object"); + cy.get(`${fieldPrefix}-name`) + .find("input") + .should("not.exist"); + + cy.get(commonlocators.jsonFormAddNewCustomFieldBtn).click({ + force: true, + }); + + cy.get(`${fieldPrefix}-name`) + .find("input") + .should("exist"); + + cy.selectDropdownValue(commonlocators.jsonFormFieldType, /^Text Input$/); + cy.closePropertyPane(); + }); + + it("modifies field type Multi-Select to Array", () => { + cy.openPropertyPane("jsonformwidget"); + + cy.get(`${fieldPrefix}-hobbies`) + .find(".rc-select-multiple") + .should("exist"); + + cy.openFieldConfiguration("hobbies"); + cy.selectDropdownValue(commonlocators.jsonFormFieldType, "Array"); + cy.get(`${fieldPrefix}-hobbies`).then((hobbies) => { + cy.wrap(hobbies) + .find(".t--jsonformfield-array-add-btn") + .should("exist"); + cy.wrap(hobbies) + .find("input") + .should("have.length", 2); + cy.wrap(hobbies) + .find(".t--jsonformfield-array-delete-btn") + .should("have.length", 2); + }); + + cy.selectDropdownValue(commonlocators.jsonFormFieldType, /^Text Input$/); + cy.closePropertyPane(); + }); +}); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/FormWidgets/JSONFormWidget/JSONForm_FieldProperties_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/FormWidgets/JSONFormWidget/JSONForm_FieldProperties_spec.js new file mode 100644 index 0000000000..baf9a0e4b6 --- /dev/null +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/FormWidgets/JSONFormWidget/JSONForm_FieldProperties_spec.js @@ -0,0 +1,283 @@ +const commonlocators = require("../../../../../locators/commonlocators.json"); +const dslWithoutSchema = require("../../../../../fixtures/jsonFormDslWithoutSchema.json"); + +const fieldPrefix = ".t--jsonformfield"; + +describe("Text Field Property Control", () => { + before(() => { + const schema = { + name: "John", + }; + cy.addDsl(dslWithoutSchema); + cy.openPropertyPane("jsonformwidget"); + cy.testJsontext("sourcedata", JSON.stringify(schema)); + }); + + it("has valid default text", () => { + cy.openFieldConfiguration("name"); + cy.get(".t--property-control-defaultvalue").contains("{{sourceData.name}}"); + }); + + it("updated field with change in default text", () => { + const defaultValue = "New default text"; + cy.testJsontext("defaultvalue", "New default text").wait(200); + cy.get(`${fieldPrefix}-name input`).should("have.value", defaultValue); + }); + + it("throws max character error when exceeds maxChar limit", () => { + cy.testJsontext("maxchars", 5); + cy.get(`${fieldPrefix}-name input`).click(); + cy.get(".bp3-popover-content").should(($x) => { + expect($x).contain( + "Default Text length must be less than Max Chars allowed", + ); + }); + cy.testJsontext("maxchars", ""); + }); + + it("sets placeholder", () => { + const placeholderText = "First name"; + cy.testJsontext("placeholder", placeholderText); + cy.get(`${fieldPrefix}-name input`) + .invoke("attr", "placeholder") + .should("contain", placeholderText); + }); + + it("sets valid property with custom error message", () => { + cy.testJsontext("valid", "false"); + cy.get(`${fieldPrefix}-name input`) + .clear() + .type("abcd"); + cy.get(".bp3-popover-content").contains("Invalid input"); + + cy.testJsontext("errormessage", "Custom error message"); + cy.get(`${fieldPrefix}-name input`).click({ force: true }); + cy.get(".bp3-popover-content").contains("Custom error message"); + }); + + it("hides field when visible switched off", () => { + cy.togglebarDisable(`.t--property-control-visible input`); + cy.get(`${fieldPrefix}-name`).should("not.exist"); + cy.wait(500); + cy.togglebar(`.t--property-control-visible input`); + cy.get(`${fieldPrefix}-name`).should("exist"); + }); + + it("disables field when disabled switched on", () => { + cy.togglebar(`.t--property-control-disabled input`); + cy.get(`${fieldPrefix}-name input`).each(($el) => { + cy.wrap($el).should("have.attr", "disabled"); + }); + + cy.togglebarDisable(`.t--property-control-disabled input`); + }); +}); + +describe("Checkbox Field Property Control", () => { + before(() => { + const schema = { + check: false, + }; + cy.addDsl(dslWithoutSchema); + cy.openPropertyPane("jsonformwidget"); + cy.testJsontext("sourcedata", JSON.stringify(schema)); + cy.openFieldConfiguration("check"); + cy.selectDropdownValue(commonlocators.jsonFormFieldType, "Checkbox"); + }); + + it("has default property", () => { + cy.get(".t--property-control-defaultselected").contains( + "{{sourceData.check}}", + ); + }); + + it("should update field checked state when default selected changed", () => { + cy.testJsontext("defaultselected", "{{true}}"); + cy.get(`${fieldPrefix}-check input`).should("be.checked"); + }); + + it("hides field when visible switched off", () => { + cy.togglebarDisable(`.t--property-control-visible input`); + cy.get(`${fieldPrefix}-check`).should("not.exist"); + cy.wait(500); + cy.togglebar(`.t--property-control-visible input`); + cy.get(`${fieldPrefix}-check`).should("exist"); + }); + + it("disables field when disabled switched on", () => { + cy.togglebar(`.t--property-control-disabled input`); + cy.get(`${fieldPrefix}-check input`).each(($el) => { + cy.wrap($el).should("have.attr", "disabled"); + }); + + cy.togglebarDisable(`.t--property-control-disabled input`); + }); +}); + +describe("Switch Field Property Control", () => { + before(() => { + const schema = { + switch: true, + }; + cy.addDsl(dslWithoutSchema); + cy.openPropertyPane("jsonformwidget"); + cy.testJsontext("sourcedata", JSON.stringify(schema)); + cy.openFieldConfiguration("switch"); + }); + + it("has default property", () => { + cy.get(".t--property-control-defaultselected").contains( + "{{sourceData.switch}}", + ); + }); + + it("should update field checked state when default selected changed", () => { + cy.testJsontext("defaultselected", "{{false}}"); + cy.get(`${fieldPrefix}-switch label.bp3-control.bp3-switch`).should( + "have.class", + "t--switch-widget-inactive", + ); + }); + + it("hides field when visible switched off", () => { + cy.togglebarDisable(`.t--property-control-visible input`); + cy.get(`${fieldPrefix}-switch`).should("not.exist"); + cy.wait(500); + cy.togglebar(`.t--property-control-visible input`); + cy.get(`${fieldPrefix}-switch`).should("exist"); + }); + + it("disables field when disabled switched on", () => { + cy.togglebar(`.t--property-control-disabled input`); + cy.get(`${fieldPrefix}-switch input`).each(($el) => { + cy.wrap($el).should("have.attr", "disabled"); + }); + + cy.togglebarDisable(`.t--property-control-disabled input`); + }); +}); + +describe("Select Field Property Control", () => { + before(() => { + const schema = { + state: "Karnataka", + }; + cy.addDsl(dslWithoutSchema); + cy.openPropertyPane("jsonformwidget"); + cy.testJsontext("sourcedata", JSON.stringify(schema)); + cy.openFieldConfiguration("state"); + cy.selectDropdownValue(commonlocators.jsonFormFieldType, /^Select$/); + }); + + it("has valid default value", () => { + cy.get(".t--property-control-defaultvalue").contains( + "{{sourceData.state}}", + ); + }); + + it("makes select filterable", () => { + // click select field and filter input should not exist + cy.get(`${fieldPrefix}-state .bp3-control-group`).click({ force: true }); + cy.get(`.bp3-select-popover .bp3-input-group`).should("not.exist"); + + // toggle filterable -> true in property pane + cy.togglebar(`.t--property-control-filterable input`); + + // click select field and filter input should exist + cy.get(`${fieldPrefix}-state .bp3-control-group`).click({ force: true }); + cy.get(`.bp3-select-popover .bp3-input-group`).should("exist"); + }); + + it("hides field when visible switched off", () => { + cy.togglebarDisable(`.t--property-control-visible input`); + cy.get(`${fieldPrefix}-state`).should("not.exist"); + cy.wait(500); + cy.togglebar(`.t--property-control-visible input`); + cy.get(`${fieldPrefix}-state`).should("exist"); + }); + + it("disables field when disabled switched on", () => { + cy.togglebar(`.t--property-control-disabled input`); + cy.get(`${fieldPrefix}-state button.bp3-button`).should( + "have.class", + "bp3-disabled", + ); + + cy.togglebarDisable(`.t--property-control-disabled input`); + }); +}); + +describe("Multi-Select Field Property Control", () => { + before(() => { + const schema = { + hobbies: [], + }; + cy.addDsl(dslWithoutSchema); + cy.openPropertyPane("jsonformwidget"); + cy.testJsontext("sourcedata", JSON.stringify(schema)); + cy.openFieldConfiguration("hobbies"); + }); + + it("has valid default value", () => { + cy.get(".t--property-control-defaultvalue").contains( + "{{sourceData.hobbies}}", + ); + cy.closePropertyPane(); + }); + + it("adds placeholder text", () => { + cy.openPropertyPane("jsonformwidget"); + cy.openFieldConfiguration("hobbies"); + + cy.testJsontext("placeholder", "Select placeholder"); + cy.wait(2000); + cy.get(`.rc-select-selection-placeholder`).contains("Select placeholder"); + }); + + it("hides field when visible switched off", () => { + cy.togglebarDisable(`.t--property-control-visible input`); + cy.get(`${fieldPrefix}-hobbies`).should("not.exist"); + cy.wait(500); + cy.togglebar(`.t--property-control-visible input`); + cy.get(`${fieldPrefix}-hobbies`).should("exist"); + }); + + it("disables field when disabled switched on", () => { + cy.togglebar(`.t--property-control-disabled input`); + cy.get(`${fieldPrefix}-hobbies .rc-select-multiple`).should( + "have.class", + "rc-select-disabled", + ); + + cy.togglebarDisable(`.t--property-control-disabled input`); + }); +}); + +describe("Radio group Field Property Control", () => { + before(() => { + const sourceData = { + radio: "Y", + }; + cy.addDsl(dslWithoutSchema); + cy.openPropertyPane("jsonformwidget"); + cy.testJsontext("sourcedata", JSON.stringify(sourceData)); + cy.openFieldConfiguration("radio"); + cy.selectDropdownValue(commonlocators.jsonFormFieldType, "Radio Group"); + }); + + it("has valid default value", () => { + cy.get(".t--property-control-defaultselectedvalue").contains( + "{{sourceData.radio}}", + ); + + cy.get(`${fieldPrefix}-radio input`).should("have.value", "Y"); + }); + + it("hides field when visible switched off", () => { + cy.togglebarDisable(`.t--property-control-visible input`); + cy.get(`${fieldPrefix}-radio`).should("not.exist"); + cy.wait(500); + cy.togglebar(`.t--property-control-visible input`); + cy.get(`${fieldPrefix}-radio`).should("exist"); + }); +}); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/FormWidgets/JSONFormWidget/JSONForm_FormBindings_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/FormWidgets/JSONFormWidget/JSONForm_FormBindings_spec.js new file mode 100644 index 0000000000..5c6f9159bd --- /dev/null +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/FormWidgets/JSONFormWidget/JSONForm_FormBindings_spec.js @@ -0,0 +1,423 @@ +const dslWithSchema = require("../../../../../fixtures/jsonFormDslWithSchema.json"); +const widgetsPage = require("../../../../../locators/Widgets.json"); + +const fieldPrefix = ".t--jsonformfield"; +const propertyControlPrefix = ".t--property-control"; +const backBtn = ".t--property-pane-back-btn"; + +describe("JSON Form Widget Form Bindings", () => { + beforeEach(() => { + cy.addDsl(dslWithSchema); + }); + + it("updates formData when field value changes", () => { + const expectedInitialFormData = { + age: 30, + dob: "10/12/1992", + migrant: false, + address: { street: "Koramangala", city: "Bangalore" }, + hobbies: ["travelling", "swimming"], + education: [{ college: "MIT", year: "20/10/2014" }], + name: "John", + }; + const updatedFormData = { + age: 40, + dob: "10/12/1992", + migrant: false, + address: { street: "Indranagar", city: "Bangalore" }, + hobbies: ["travelling"], + education: [{ college: "IIT", year: "20/10/2014" }], + name: "Test", + }; + // Bind formData to Text1 widget text property + cy.openPropertyPane("textwidget"); + cy.testJsontext("text", "{{JSON.stringify(JSONForm1.formData)}}"); + cy.closePropertyPane(); + + // Validate initial form data + cy.get(`${widgetsPage.textWidget} .bp3-ui-text`).then(($el) => { + const formData = JSON.parse($el.text()); + cy.wrap(formData).should("deep.equal", expectedInitialFormData); + }); + + // Modify form field values + cy.get(`${fieldPrefix}-name input`) + .clear({ force: true }) + .type(updatedFormData.name); + cy.get(`${fieldPrefix}-age input`) + .clear({ force: true }) + .clear({ force: true }) + .type(updatedFormData.age); + cy.get(`${fieldPrefix}-address-street input`) + .clear({ force: true }) + .type(updatedFormData.address.street); + cy.get(`${fieldPrefix}-hobbies .rc-select-selection-item`) + .contains("swimming") + .siblings(".rc-select-selection-item-remove") + .click({ force: true }); + cy.get(`${fieldPrefix}-education-0--college input`) + .clear({ force: true }) + .type(updatedFormData.education[0].college) + .wait(200); + + cy.wait(1000); + // Check if modified text updates formData + cy.get(`${widgetsPage.textWidget} .bp3-ui-text`).then(($el) => { + const formData = JSON.parse($el.text()); + cy.wrap(formData).should("deep.equal", updatedFormData); + }); + }); + + it("updates fieldState", () => { + const expectedInitialFieldState = { + name: { + isDisabled: false, + isVisible: true, + isRequired: false, + isValid: true, + }, + age: { + isDisabled: false, + isVisible: true, + isRequired: false, + isValid: true, + }, + dob: { + isDisabled: false, + isVisible: true, + isRequired: false, + isValid: true, + }, + migrant: { + isDisabled: false, + isVisible: true, + isRequired: false, + isValid: true, + isValid: true, + }, + address: { + street: { + isDisabled: false, + isVisible: true, + isRequired: false, + isValid: true, + }, + city: { + isDisabled: false, + isVisible: true, + isRequired: false, + isValid: true, + }, + }, + education: [ + { + college: { + isDisabled: false, + isVisible: true, + isRequired: false, + isValid: true, + }, + year: { + isDisabled: false, + isVisible: true, + isRequired: false, + isValid: true, + }, + }, + ], + hobbies: { + isDisabled: false, + isVisible: true, + isRequired: false, + isValid: true, + filterText: "", + }, + }; + + const expectedUpdatedFieldState = { + name: { + isDisabled: false, + isVisible: true, + isRequired: true, + isValid: false, + }, + age: { + isDisabled: true, + isVisible: true, + isRequired: false, + isValid: true, + }, + dob: { + isDisabled: false, + isVisible: true, + isRequired: false, + isValid: true, + }, + migrant: { + isDisabled: false, + isVisible: false, + isRequired: false, + isValid: true, + }, + address: { + street: { + isDisabled: false, + isVisible: true, + isRequired: true, + isValid: false, + }, + city: { + isDisabled: false, + isVisible: true, + isRequired: false, + isValid: true, + }, + }, + education: [ + { + college: { + isDisabled: false, + isVisible: true, + isRequired: true, + isValid: false, + }, + year: { + isDisabled: false, + isVisible: false, + isRequired: false, + isValid: true, + }, + }, + ], + hobbies: { + isDisabled: false, + isVisible: true, + isRequired: false, + isValid: true, + filterText: "", + }, + }; + + cy.openPropertyPane("textwidget"); + cy.get(".t--property-control-text .CodeMirror textarea") + .first() + .clear({ + force: true, + }); + cy.testJsontext("text", "{{JSON.stringify(JSONForm1.fieldState)}}"); + cy.closePropertyPane(); + + cy.wait(3000); + + cy.get(`${widgetsPage.textWidget} .bp3-ui-text`).then(($el) => { + const formData = JSON.parse($el.text()); + cy.wrap(formData).should("deep.equal", expectedInitialFieldState); + }); + + cy.openPropertyPane("jsonformwidget"); + + // name.required -> true + cy.openFieldConfiguration("name"); + cy.togglebar(`${propertyControlPrefix}-required input`); + cy.get(backBtn) + .click({ force: true }) + .wait(500); + + // age.disabled -> true + cy.openFieldConfiguration("age"); + cy.togglebar(`${propertyControlPrefix}-disabled input`); + cy.get(backBtn) + .click({ force: true }) + .wait(500); + + // migrant.visible -> false + cy.openFieldConfiguration("migrant"); + cy.togglebarDisable(`${propertyControlPrefix}-visible input`); + cy.get(backBtn) + .click({ force: true }) + .wait(500); + + // address.street.required -> true + cy.openFieldConfiguration("address"); + cy.openFieldConfiguration("street"); + cy.togglebar(`${propertyControlPrefix}-required input`); + cy.get(backBtn) + .click({ force: true }) + .wait(500); + cy.get(backBtn) + .click({ force: true }) + .wait(500); + + // education.college.required -> true + // education.year.visible -> false + cy.openFieldConfiguration("education"); + cy.openFieldConfiguration("__array_item__"); + cy.openFieldConfiguration("college"); + cy.togglebar(`${propertyControlPrefix}-required input`); + cy.get(backBtn) + .click({ force: true }) + .wait(500); + cy.openFieldConfiguration("year"); + cy.togglebarDisable(`${propertyControlPrefix}-visible input`); + cy.get(backBtn) + .click({ force: true }) + .wait(500); + + cy.closePropertyPane(); + + cy.get(`${fieldPrefix}-name input`).clear({ force: true }); + cy.get(`${fieldPrefix}-address-street input`).clear({ force: true }); + cy.get(`${fieldPrefix}-address-city input`).clear({ force: true }); + cy.get(`${fieldPrefix}-education-0--college input`) + .clear({ force: true }) + .wait(500); + + cy.wait(3000); + + cy.get(`${widgetsPage.textWidget} .bp3-ui-text`).then(($el) => { + const formState = JSON.parse($el.text()); + cy.wrap(formState).should("deep.equal", expectedUpdatedFieldState); + }); + }); + + it("change field accessor should reflect in fieldState", () => { + const expectedFieldStateChange = { + firstName: { + isDisabled: false, + isVisible: true, + isRequired: false, + isValid: true, + }, + age: { + isDisabled: false, + isVisible: true, + isRequired: false, + isValid: true, + }, + dob: { + isDisabled: false, + isVisible: true, + isRequired: false, + isValid: true, + }, + migrant: { + isDisabled: false, + isVisible: true, + isRequired: false, + isValid: true, + }, + address: { + street: { + isDisabled: false, + isVisible: true, + isRequired: false, + isValid: true, + }, + city: { + isDisabled: false, + isVisible: true, + isRequired: false, + isValid: true, + }, + }, + education: [ + { + graduatingCollege: { + isDisabled: false, + isVisible: true, + isRequired: false, + isValid: true, + }, + year: { + isDisabled: false, + isVisible: true, + isRequired: false, + isValid: true, + }, + }, + ], + hobbies: { + isDisabled: false, + isVisible: true, + isRequired: false, + isValid: true, + filterText: "", + }, + }; + + cy.openPropertyPane("textwidget"); + cy.get(".t--property-control-text .CodeMirror textarea") + .first() + .clear({ + force: true, + }); + cy.testJsontext("text", "{{JSON.stringify(JSONForm1.fieldState)}}"); + + cy.openPropertyPane("jsonformwidget"); + + // Change accessor name -> firstName + cy.openFieldConfiguration("name"); + cy.testJsontext("propertyname", "firstName"); + cy.wait(1000); + + cy.get(backBtn) + .click({ force: true }) + .wait(500); + + // Change accessor education -> college to education -> graduatingCollege + cy.openFieldConfiguration("education"); + cy.openFieldConfiguration("__array_item__"); + cy.openFieldConfiguration("college"); + cy.testJsontext("propertyname", "graduatingCollege"); + + cy.wait(5000); + + // Verify if formState reflects accessor change + cy.get(`${widgetsPage.textWidget} .bp3-ui-text`).then(($el) => { + const formState = JSON.parse($el.text()); + cy.wrap(formState).should("deep.equal", expectedFieldStateChange); + }); + }); + + it("change field accessor should reflect in formData", () => { + const expectedFormDataChange = { + age: 30, + dob: "10/12/1992", + migrant: false, + address: { street: "Koramangala", city: "Bangalore" }, + hobbies: ["travelling", "swimming"], + education: [{ graduatingCollege: "MIT", year: "20/10/2014" }], + firstName: "John", + }; + + cy.openPropertyPane("jsonformwidget"); + + // Change accessor name -> firstName + cy.openFieldConfiguration("name"); + cy.testJsontext("propertyname", "firstName"); + cy.wait(1000); + + cy.get(backBtn) + .click({ force: true }) + .wait(500); + + // Change accessor education -> college to education -> graduatingCollege + cy.openFieldConfiguration("education"); + cy.openFieldConfiguration("__array_item__"); + cy.openFieldConfiguration("college"); + cy.testJsontext("propertyname", "graduatingCollege"); + + cy.wait(5000); + + cy.openPropertyPane("textwidget"); + cy.testJsontext("text", "{{JSON.stringify(JSONForm1.formData)}}"); + + cy.wait(1000); + + // Verify if formData reflects accessor change + cy.get(`${widgetsPage.textWidget} .bp3-ui-text`).then(($el) => { + const formData = JSON.parse($el.text()); + cy.wrap(formData).should("deep.equal", expectedFormDataChange); + }); + }); +}); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/FormWidgets/JSONFormWidget/JSONForm_FormProperties_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/FormWidgets/JSONFormWidget/JSONForm_FormProperties_spec.js new file mode 100644 index 0000000000..4dbddc35d9 --- /dev/null +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/FormWidgets/JSONFormWidget/JSONForm_FormProperties_spec.js @@ -0,0 +1,70 @@ +const commonlocators = require("../../../../../locators/commonlocators.json"); +const dslWithSchema = require("../../../../../fixtures/jsonFormDslWithSchema.json"); + +const backBtn = ".t--property-pane-back-btn"; +const fieldPrefix = ".t--jsonformfield"; +const propertyControlPrefix = ".t--property-control"; + +describe("JSON Form Widget Form Bindings", () => { + before(() => { + cy.addDsl(dslWithSchema); + }); + + it("should have all the fields under field configuration", () => { + cy.openPropertyPane("jsonformwidget"); + const fieldNames = [ + "name", + "age", + "dob", + "migrant", + "address", + "education", + "hobbies", + ]; + + fieldNames.forEach((fieldName) => { + cy.get(`[data-rbd-draggable-id='${fieldName}']`).should("exist"); + }); + }); + + it("Field Configuration - adds new custom field", () => { + cy.openPropertyPane("jsonformwidget"); + + // Add new field + cy.get(commonlocators.jsonFormAddNewCustomFieldBtn).click({ + force: true, + }); + + // Check for the presence of newly added custom field + cy.get(`[data-rbd-draggable-id='customField1']`).should("exist"); + }); + + it("Disabled Invalid Forms - disables the submit button when form has invalid field(s)", () => { + cy.get("button") + .contains("Submit") + .parent("button") + .should("not.have.attr", "disabled"); + + // make name field required + cy.openFieldConfiguration("name"); + cy.togglebar(`${propertyControlPrefix}-required input`); + + cy.get(backBtn).click({ force: true }); + cy.get(`${fieldPrefix}-name input`) + .clear() + .wait(300); + cy.get("button") + .contains("Submit") + .parent("button") + .should("have.attr", "disabled"); + + cy.get(`${fieldPrefix}-name input`) + .type("JOHN") + .wait(300); + + cy.get("button") + .contains("Submit") + .parent("button") + .should("not.have.attr", "disabled"); + }); +}); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/FormWidgets/JSONFormWidget/JSONForm_Reset_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/FormWidgets/JSONFormWidget/JSONForm_Reset_spec.js new file mode 100644 index 0000000000..1745ef9f9f --- /dev/null +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/FormWidgets/JSONFormWidget/JSONForm_Reset_spec.js @@ -0,0 +1,146 @@ +const dslWithSchema = require("../../../../../fixtures/jsonFormDslWithSchema.json"); + +const fieldPrefix = ".t--jsonformfield"; + +describe("JSON Form reset", () => { + beforeEach(() => { + cy.addDsl(dslWithSchema); + }); + + it("updates formData when field value changes", () => { + const initialFormData = { + age: 30, + dob: "10/12/1992", + migrant: false, + address: { street: "Koramangala", city: "Bangalore" }, + hobbies: ["travelling", "swimming"], + education: [{ college: "MIT", year: "20/10/2014" }], + name: "John", + }; + const updatedFormData = { + age: 40, + dob: "10/12/1992", + migrant: false, + address: { street: "Indranagar", city: "Bangalore" }, + hobbies: ["travelling"], + education: [{ college: "IIT", year: "20/10/2014" }], + name: "Test", + }; + + // Verify current field values + cy.get(`${fieldPrefix}-name input`).should( + "have.value", + initialFormData.name, + ); + cy.get(`${fieldPrefix}-age input`).should( + "have.value", + initialFormData.age, + ); + cy.get(`${fieldPrefix}-dob input`).should( + "have.value", + initialFormData.dob, + ); + cy.get(`${fieldPrefix}-address-street input`).should( + "have.value", + initialFormData.address.street, + ); + cy.get(`${fieldPrefix}-address-city input`).should( + "have.value", + initialFormData.address.city, + ); + cy.get(`${fieldPrefix}-education-0--college input`).should( + "have.value", + initialFormData.education[0].college, + ); + cy.get(`${fieldPrefix}-education-0--year input`).should( + "have.value", + initialFormData.education[0].year, + ); + + // Modify field values + cy.get(`${fieldPrefix}-name input`) + .clear({ force: true }) + .type(updatedFormData.name); + cy.get(`${fieldPrefix}-age input`) + .clear({ force: true }) + .clear({ force: true }) + .type(updatedFormData.age); + cy.get(`${fieldPrefix}-address-street input`) + .clear({ force: true }) + .type(updatedFormData.address.street); + cy.get(`${fieldPrefix}-hobbies .rc-select-selection-item`) + .contains("swimming") + .siblings(".rc-select-selection-item-remove") + .click({ force: true }); + cy.get(`${fieldPrefix}-education-0--college input`) + .clear({ force: true }) + .type(updatedFormData.education[0].college) + .wait(200); + + // Verify new field values + cy.get(`${fieldPrefix}-name input`).should( + "have.value", + updatedFormData.name, + ); + cy.get(`${fieldPrefix}-age input`).should( + "have.value", + updatedFormData.age, + ); + cy.get(`${fieldPrefix}-dob input`).should( + "have.value", + updatedFormData.dob, + ); + cy.get(`${fieldPrefix}-address-street input`).should( + "have.value", + updatedFormData.address.street, + ); + cy.get(`${fieldPrefix}-address-city input`).should( + "have.value", + updatedFormData.address.city, + ); + cy.get(`${fieldPrefix}-education-0--college input`).should( + "have.value", + updatedFormData.education[0].college, + ); + cy.get(`${fieldPrefix}-education-0--year input`).should( + "have.value", + updatedFormData.education[0].year, + ); + + // Reset form + cy.get("button") + .contains("Reset") + .parent("button") + .click({ force: true }); + + // Verify initial field values + cy.get(`${fieldPrefix}-name input`).should( + "have.value", + initialFormData.name, + ); + cy.get(`${fieldPrefix}-age input`).should( + "have.value", + initialFormData.age, + ); + cy.get(`${fieldPrefix}-dob input`).should( + "have.value", + initialFormData.dob, + ); + cy.get(`${fieldPrefix}-address-street input`).should( + "have.value", + initialFormData.address.street, + ); + cy.get(`${fieldPrefix}-address-city input`).should( + "have.value", + initialFormData.address.city, + ); + cy.get(`${fieldPrefix}-education-0--college input`).should( + "have.value", + initialFormData.education[0].college, + ); + cy.get(`${fieldPrefix}-education-0--year input`).should( + "have.value", + initialFormData.education[0].year, + ); + }); +}); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/FormWidgets/JSONFormWidget/JSONForm_UnicodeKeys_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/FormWidgets/JSONFormWidget/JSONForm_UnicodeKeys_spec.js new file mode 100644 index 0000000000..d48f2ba744 --- /dev/null +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/FormWidgets/JSONFormWidget/JSONForm_UnicodeKeys_spec.js @@ -0,0 +1,241 @@ +const dslWithoutSchema = require("../../../../../fixtures/jsonFormDslWithoutSchema.json"); +const jsonFormUnicodeDSLWithoutSourceData = require("../../../../../fixtures/jsonFormUnicodeDSLWithoutSourceData.json"); +const widgetsPage = require("../../../../../locators/Widgets.json"); + +const fieldPrefix = ".t--jsonformfield"; +const backBtn = ".t--property-pane-back-btn"; + +describe("JSON Form Widget Unicode keys", () => { + it("generates fields with valid source data json", () => { + cy.addDsl(dslWithoutSchema); + const sourceData = { + नाम: "John", + суроға: { + شارع: "Koramangala", + }, + การศึกษา: [ + { + କଲେଜ: "MIT", + }, + ], + }; + + cy.openPropertyPane("jsonformwidget"); + cy.testJsontext("sourcedata", JSON.stringify(sourceData)); + cy.closePropertyPane(); + + cy.get(`${fieldPrefix}-xn__l2bm1c label`).contains("नाम"); + cy.get(`${fieldPrefix}-xn__l2bm1c input`).then((input) => { + cy.wrap(input).should("have.value", "John"); + cy.wrap(input) + .invoke("attr", "type") + .should("contain", "text"); + }); + + cy.get(`${fieldPrefix}-xn__80a1afdk69b label`).should("have.length", 2); + cy.get(`${fieldPrefix}-xn__80a1afdk69b-xn__mgbuhw label`).contains("شارع"); + cy.get(`${fieldPrefix}-xn__80a1afdk69b-xn__mgbuhw input`).then((input) => { + cy.wrap(input).should("have.value", "Koramangala"); + cy.wrap(input) + .invoke("attr", "type") + .should("contain", "text"); + }); + + cy.get(`${fieldPrefix}-xn__12ca5huag4ce3a label`).should("have.length", 2); + + cy.get(`${fieldPrefix}-xn__12ca5huag4ce3a-0--xn__ohco9d4d label`).contains( + "କଲେଜ", + ); + cy.get(`${fieldPrefix}-xn__12ca5huag4ce3a-0--xn__ohco9d4d input`).then( + (input) => { + cy.wrap(input).should("have.value", "MIT"); + cy.wrap(input) + .invoke("attr", "type") + .should("contain", "text"); + }, + ); + + cy.get( + `${fieldPrefix}-xn__12ca5huag4ce3a .t--jsonformfield-array-delete-btn .t--text`, + ).should("have.text", "Delete"); + cy.get( + `${fieldPrefix}-xn__12ca5huag4ce3a .t--jsonformfield-array-add-btn .t--text`, + ).should("have.text", "Add New"); + }); + + it("modifies field when source data changes", () => { + cy.addDsl(jsonFormUnicodeDSLWithoutSourceData); + + const modifiedSourceData = { + "पहला नाम": "John", + "अंतिम नाम": "Doe", + суроға: { + شارع: "Koramangala", + }, + การศึกษา: [ + { + କଲେଜ: "MIT", + 卒業の日: "21/03/2010", + }, + ], + }; + + cy.openPropertyPane("jsonformwidget"); + cy.testJsontext("sourcedata", JSON.stringify(modifiedSourceData)); + cy.closePropertyPane(); + + cy.get(`${fieldPrefix}-xn____xvdesr5bxbc label`).contains("पहला नाम"); + cy.get(`${fieldPrefix}-xn____xvdesr5bxbc input`).then((input) => { + cy.wrap(input).should("have.value", "John"); + cy.wrap(input) + .invoke("attr", "type") + .should("contain", "text"); + }); + + cy.get(`${fieldPrefix}-xn____qtdi9jva8ac1kf label`).contains("अंतिम नाम"); + cy.get(`${fieldPrefix}-xn____qtdi9jva8ac1kf input`).then((input) => { + cy.wrap(input).should("have.value", "Doe"); + cy.wrap(input) + .invoke("attr", "type") + .should("contain", "text"); + }); + + cy.get(`${fieldPrefix}-xn__80a1afdk69b label`).should("have.length", 2); + cy.get(`${fieldPrefix}-xn__80a1afdk69b-xn__mgbuhw label`).contains("شارع"); + cy.get(`${fieldPrefix}-xn__80a1afdk69b-xn__mgbuhw input`).then((input) => { + cy.wrap(input).should("have.value", "Koramangala"); + cy.wrap(input) + .invoke("attr", "type") + .should("contain", "text"); + }); + + cy.get(`${fieldPrefix}-xn__12ca5huag4ce3a label`).should("have.length", 3); + + cy.get(`${fieldPrefix}-xn__12ca5huag4ce3a-0--xn__ohco9d4d label`).contains( + "କଲେଜ", + ); + cy.get(`${fieldPrefix}-xn__12ca5huag4ce3a-0--xn__ohco9d4d input`).then( + (input) => { + cy.wrap(input).should("have.value", "MIT"); + cy.wrap(input) + .invoke("attr", "type") + .should("contain", "text"); + }, + ); + + cy.get( + `${fieldPrefix}-xn__12ca5huag4ce3a-0--xn__u9j436hvxmjkd label`, + ).contains("卒業の日"); + cy.get(`${fieldPrefix}-xn__12ca5huag4ce3a-0--xn__u9j436hvxmjkd input`).then( + (input) => { + cy.wrap(input).should("have.value", "21/03/2010"); + cy.wrap(input) + .invoke("attr", "type") + .should("contain", "text"); + }, + ); + + cy.get( + `${fieldPrefix}-xn__12ca5huag4ce3a .t--jsonformfield-array-delete-btn .t--text`, + ).should("have.text", "Delete"); + cy.get( + `${fieldPrefix}-xn__12ca5huag4ce3a .t--jsonformfield-array-add-btn .t--text`, + ).should("have.text", "Add New"); + }); + + it("change in accessor updates formData", () => { + cy.addDsl(jsonFormUnicodeDSLWithoutSourceData); + const sourceData = { + नाम: "John", + суроға: { + شارع: "Koramangala", + }, + การศึกษา: [ + { + କଲେଜ: "MIT", + }, + ], + }; + + cy.openPropertyPane("jsonformwidget"); + cy.testJsontext("sourcedata", JSON.stringify(sourceData)); + cy.closePropertyPane(); + + const expectedInitialFormData = sourceData; + + const formDataBeforeArrayAccessorChange = { + "नाम नाम": "John", + суроға: { + "شارع1 شارع": "Koramangala", + }, + การศึกษา: [ + { + କଲେଜ: "MIT", + }, + ], + }; + + const formDataAfterArrayAccessorChange = { + "नाम नाम": "John", + суроға: { + "شارع1 شارع": "Koramangala", + }, + การศึกษา: [ + { + "ସ୍ନାତକ କଲେଜ": "MIT", + }, + ], + }; + + // Bind formData to Text1 widget text property + cy.openPropertyPane("textwidget"); + cy.testJsontext("text", "{{JSON.stringify(JSONForm1.formData)}}"); + cy.closePropertyPane(); + + // Validate initial form data + cy.get(`${widgetsPage.textWidget} .bp3-ui-text`).then(($el) => { + const formData = JSON.parse($el.text()); + cy.wrap(formData).should("deep.equal", expectedInitialFormData); + }); + + cy.openPropertyPane("jsonformwidget"); + + // नाम field + cy.openFieldConfiguration("xn__l2bm1c"); + cy.testJsontext("propertyname", "नाम नाम"); + cy.get(backBtn) + .click({ force: true }) + .wait(500); + + // open field суроға -> شارع + cy.openFieldConfiguration("xn__80a1afdk69b"); + cy.openFieldConfiguration("xn__mgbuhw"); + cy.testJsontext("propertyname", "شارع1 شارع"); + cy.get(backBtn) + .click({ force: true }) + .wait(500); + cy.get(backBtn) + .click({ force: true }) + .wait(500); + + // Validate initial form data + cy.get(`${widgetsPage.textWidget} .bp3-ui-text`).then(($el) => { + const formData = JSON.parse($el.text()); + cy.wrap(formData).should("deep.equal", formDataBeforeArrayAccessorChange); + }); + + // open field การศึกษา -> array item -> କଲେଜ + cy.openFieldConfiguration("xn__12ca5huag4ce3a"); + cy.openFieldConfiguration("__array_item__"); + cy.openFieldConfiguration("xn__ohco9d4d"); + cy.testJsontext("propertyname", "ସ୍ନାତକ କଲେଜ"); + + cy.wait(5000); + + // Validate initial form data + cy.get(`${widgetsPage.textWidget} .bp3-ui-text`).then(($el) => { + const formData = JSON.parse($el.text()); + cy.wrap(formData).should("deep.equal", formDataAfterArrayAccessorChange); + }); + }); +}); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/FormWidgets/Phone_input_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/FormWidgets/Phone_input_spec.js index 588afe9e86..5714c66c7d 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/FormWidgets/Phone_input_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/FormWidgets/Phone_input_spec.js @@ -81,6 +81,11 @@ describe("Phone input widget - ", () => { }); it("should check that widget input resets on submit", () => { + cy.openPropertyPane("textwidget"); + cy.updateCodeInput( + ".t--property-control-text", + `{{PhoneInput1.text}}:{{PhoneInput1.value}}`, + ); cy.openPropertyPane(widgetName); cy.get( ".t--property-control-onsubmit .t--open-dropdown-Select-Action", @@ -90,8 +95,12 @@ describe("Phone input widget - ", () => { cy.get(widgetInput).clear(); cy.wait(300); - cy.get(widgetInput).type("1234567890{enter}"); + cy.get(widgetInput).type("1234567890"); + cy.wait(300); + cy.get(".t--widget-textwidget").should("contain", "1234567890:1234567890"); + cy.get(widgetInput).type("{enter}"); cy.wait(300); cy.get(widgetInput).should("contain.value", ""); + cy.get(".t--widget-textwidget").should("contain", ":undefined"); }); }); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/GenerateCRUD/Mongo_Spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/GenerateCRUD/Mongo_Spec.js index db01c5c424..027b0f6b73 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/GenerateCRUD/Mongo_Spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/GenerateCRUD/Mongo_Spec.js @@ -33,11 +33,11 @@ describe("Generate New CRUD Page Inside from Mongo as Data Source", function() { //TestData source - cy.get(".t--test-datasource").click(); + cy.get(".t--test-datasource").click({ force: true }); cy.wait("@testDatasource"); //Save source - cy.get(".t--save-datasource").click(); + cy.get(".t--save-datasource").click({ force: true }); //Verify page after save clicked cy.get("@createDatasource").then((httpResponse) => { @@ -124,11 +124,11 @@ describe("Generate New CRUD Page Inside from Mongo as Data Source", function() { }); //TestData source - cy.get(".t--test-datasource").click(); + cy.get(".t--test-datasource").click({ force: true }); cy.wait("@testDatasource"); //Save source - cy.get(".t--save-datasource").click(); + cy.get(".t--save-datasource").click({ force: true }); //Generate Stub for tables dropdown values also cy.wait("@getDatasourceStructure").should( diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/GitSync/Comments_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/GitSync/Comments_spec.js index 20fbda7c97..3c56d891a9 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/GitSync/Comments_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/GitSync/Comments_spec.js @@ -1,5 +1,4 @@ const commonLocators = require("../../../../locators/commonlocators.json"); -const { typeIntoDraftEditor } = require("../Comments/utils"); import commentsLocators from "../../../../locators/CommentsLocators"; const newCommentText1 = "new comment text 1"; @@ -36,7 +35,7 @@ describe("Git sync:", function() { cy.createGitBranch("ChildBranch"); // Add a comment on the child branch cy.get(commonLocators.canvas).click(50, 50); - typeIntoDraftEditor(commentsLocators.mentionsInput, newCommentText1); + cy.typeIntoDraftEditor(commentsLocators.mentionsInput, newCommentText1); cy.get(commentsLocators.mentionsInput).type("{enter}"); cy.switchGitBranch("master"); cy.get(newCommentText1).should("not.exist"); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/GitSync/DisconnectGit_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/GitSync/DisconnectGit_spec.js index 4a306ecd6e..9715f8c4a1 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/GitSync/DisconnectGit_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/GitSync/DisconnectGit_spec.js @@ -26,10 +26,6 @@ describe("Git disconnect modal:", function() { cy.get(gitSyncLocators.gitSyncModal).should("not.exist"); cy.get(gitSyncLocators.disconnectGitModal).should("exist"); - // title and info text checking - cy.get(gitSyncLocators.disconnectGitModal).contains( - Cypress.env("MESSAGES").GIT_DISCONNECTION_SUBMENU(), - ); cy.get(gitSyncLocators.disconnectGitModal).contains( Cypress.env("MESSAGES").NONE_REVERSIBLE_MESSAGE(), ); @@ -49,10 +45,10 @@ describe("Git disconnect modal:", function() { .then((state) => { const { name } = state.ui.gitSync.disconnectingGitApp; cy.get(gitSyncLocators.disconnectGitModal).contains( - Cypress.env("MESSAGES").DISCONNECT_FROM_GIT(name), + Cypress.env("MESSAGES").GIT_REVOKE_ACCESS(name), ); cy.get(gitSyncLocators.disconnectGitModal).contains( - Cypress.env("MESSAGES").TYPE_PROMO_CODE(name), + Cypress.env("MESSAGES").GIT_TYPE_REPO_NAME_FOR_REVOKING_ACCESS(name), ); }); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/GitSync/GitBugs_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/GitSync/GitBugs_spec.js new file mode 100644 index 0000000000..f26e864dd3 --- /dev/null +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/GitSync/GitBugs_spec.js @@ -0,0 +1,54 @@ +import gitSyncLocators from "../../../../locators/gitSyncLocators"; +const pagename = "ChildPage"; +const tempBranch = "tempBranch"; +const tempBranch0 = "tempBranch0"; +const mainBranch = "master"; +let repoName; + +describe("Git sync Bugs", function() { + before(() => { + cy.NavigateToHome(); + cy.createOrg(); + cy.wait("@createOrg").then((interception) => { + const newOrganizationName = interception.response.body.data.name; + cy.CreateAppForOrg(newOrganizationName, newOrganizationName); + }); + + cy.generateUUID().then((uid) => { + repoName = uid; + + cy.createTestGithubRepo(repoName); + cy.connectToGitRepo(repoName); + }); + }); + + it("Bug:10773 When user delete a resource form the child branch and merge it back to parent branch, still the deleted resource will show up in the newly created branch", () => { + // adding a new page "ChildPage" to master + cy.Createpage(pagename); + cy.get(".t--entity-name:contains('Page1')").click(); + cy.commitAndPush(); + cy.wait(2000); + cy.createGitBranch(tempBranch); + cy.CheckAndUnfoldEntityItem("PAGES"); + // verify tempBranch should contain this page + cy.get(`.t--entity-name:contains("${pagename}")`).should("be.visible"); + cy.get(`.t--entity-name:contains("${pagename}")`).click(); + // delete page from tempBranch and merge to master + cy.Deletepage(pagename); + cy.commitAndPush(); + cy.merge(mainBranch); + cy.get(gitSyncLocators.closeGitSyncModal).click(); + cy.wait(8000); + // verify ChildPage is not on master + cy.switchGitBranch(mainBranch); + cy.CheckAndUnfoldEntityItem("PAGES"); + cy.get(`.t--entity-name:contains("${pagename}")`).should("not.exist"); + // create another branch and verify deleted page doesn't exist on it + cy.createGitBranch(tempBranch0); + cy.CheckAndUnfoldEntityItem("PAGES"); + cy.get(`.t--entity-name:contains("${pagename}")`).should("not.exist"); + }); + after(() => { + cy.deleteTestGithubRepo(repoName); + }); +}); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/GitSync/Git_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/GitSync/Git_spec.js index de46f69043..59618511da 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/GitSync/Git_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/GitSync/Git_spec.js @@ -60,7 +60,6 @@ describe("Git sync:", function() { widgetsPage.buttonWidget, commonlocators.buttonInner, ); - cy.get(homePage.publishButton).click(); cy.get(gitSyncLocators.commitCommentInput).type("Initial Commit"); cy.get(gitSyncLocators.commitButton).click(); @@ -118,6 +117,7 @@ describe("Git sync:", function() { cy.commitAndPush(); cy.merge(mainBranch); cy.get(gitSyncLocators.closeGitSyncModal).click(); + cy.wait(8000); cy.switchGitBranch(mainBranch); cy.contains("NewPage"); }); @@ -185,9 +185,8 @@ describe("Git sync:", function() { cy.get(gitSyncLocators.gitPullCount); cy.get(gitSyncLocators.bottomBarPullButton).click(); - cy.contains(Cypress.env("MESSAGES").GIT_CONFLICTING_INFO()); - cy.get("body").type("{esc}"); + cy.xpath("//span[@name='close-modal']").click({ force: true }); }); it("clicking '+' icon on bottom bar should open deploy popup", function() { @@ -214,7 +213,6 @@ describe("Git sync:", function() { 201, ); cy.get("#loading").should("not.exist"); - // eslint-disable-next-line cypress/no-unnecessary-waiting cy.wait(2000); cy.AppSetupForRename(); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/GitSync/SwitchBranches_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/GitSync/SwitchBranches_spec.js index 3b3b18c9b5..2f3ffb6245 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/GitSync/SwitchBranches_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/GitSync/SwitchBranches_spec.js @@ -120,6 +120,7 @@ describe("Git sync:", function() { it("makes branch specific resource updates", function() { cy.switchGitBranch(childBranchKey); cy.CheckAndUnfoldEntityItem("QUERIES/JS"); + cy.CheckAndUnfoldEntityItem("PAGES"); cy.GlobalSearchEntity("ParentPage1"); cy.RenameEntity("ParentPageRenamed", true); cy.GlobalSearchEntity("ParentApi1"); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/LayoutWidgets/List_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/LayoutWidgets/List_spec.js index 5af2edf637..23719cf0a8 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/LayoutWidgets/List_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/LayoutWidgets/List_spec.js @@ -1,3 +1,5 @@ +/// + const commonlocators = require("../../../../locators/commonlocators.json"); const widgetsPage = require("../../../../locators/Widgets.json"); const dsl = require("../../../../fixtures/listdsl.json"); @@ -8,11 +10,13 @@ describe("Container Widget Functionality", function() { before(() => { cy.addDsl(dsl); + cy.wait(5000); }); - it("List-Unckeck Visible field Validation", function() { + it("1. List-Unckeck Visible field Validation", function() { // Open Property pane - cy.SearchEntityandOpen("List1"); + cy.CheckAndUnfoldEntityItem("WIDGETS"); + cy.selectEntityByName("List1"); //Uncheck the disabled checkbox and validate cy.UncheckWidgetProperties(commonlocators.visibleCheckbox); cy.PublishtheApp(); @@ -20,9 +24,10 @@ describe("Container Widget Functionality", function() { cy.get(publishPage.backToEditor).click({ force: true }); }); - it("List-Check Visible field Validation", function() { + it("2. List-Check Visible field Validation", function() { // Open Property pane - cy.SearchEntityandOpen("List1"); + cy.CheckAndUnfoldEntityItem("WIDGETS"); + cy.selectEntityByName("List1"); //Check the disableed checkbox and Validate cy.CheckWidgetProperties(commonlocators.visibleCheckbox); cy.PublishtheApp(); @@ -30,9 +35,10 @@ describe("Container Widget Functionality", function() { cy.get(publishPage.backToEditor).click({ force: true }); }); - it("Toggle JS - List-Unckeck Visible field Validation", function() { + it("3. Toggle JS - List-Unckeck Visible field Validation", function() { // Open Property pane - cy.SearchEntityandOpen("List1"); + cy.CheckAndUnfoldEntityItem("WIDGETS"); + cy.selectEntityByName("List1"); //Uncheck the disabled checkbox using JS and validate cy.get(widgetsPage.toggleVisible).click({ force: true }); cy.testJsontext("visible", "false"); @@ -41,9 +47,10 @@ describe("Container Widget Functionality", function() { cy.get(publishPage.backToEditor).click({ force: true }); }); - it("Toggle JS - List-Check Visible field Validation", function() { + it("4. Toggle JS - List-Check Visible field Validation", function() { // Open Property pane - cy.SearchEntityandOpen("List1"); + cy.CheckAndUnfoldEntityItem("WIDGETS"); + cy.selectEntityByName("List1"); //Check the disabled checkbox using JS and Validate cy.testJsontext("visible", "true"); cy.PublishtheApp(); @@ -51,16 +58,20 @@ describe("Container Widget Functionality", function() { cy.get(publishPage.backToEditor).click({ force: true }); }); - it("checks if list shows correct no. of items", function() { + it("5. checks if list shows correct no. of items", function() { // Verify the length of list cy.get(commonlocators.containerWidget).then(function($lis) { expect($lis).to.have.length(2); }); }); - it("checks currentItem binding", function() { + it("6. checks currentItem binding", function() { // Open property pane - cy.SearchEntityandOpen("Text1"); + cy.CheckAndUnfoldEntityItem("WIDGETS"); + cy.CheckAndUnfoldEntityItem("List1"); + cy.CheckAndUnfoldEntityItem("Container1"); + cy.selectEntityByName("Text1"); + //cy.SearchEntityandOpen("Text1"); cy.testJsontext("text", `{{currentItem.first_name}}`); cy.wait(1000); @@ -72,11 +83,36 @@ describe("Container Widget Functionality", function() { }); }); - it("checks button action", function() { + it("7. doesn't alter the no of items present when invalid item spacing is entered", () => { + // Open Property pane + cy.CheckAndUnfoldEntityItem("WIDGETS"); + cy.selectEntityByName("List1"); + // Update an invalid value to item spacing + cy.testJsontext("itemspacing\\(" + "px" + "\\)", "-"); + cy.wait(2000); + + // Verify the length of list + cy.get(commonlocators.containerWidget).then(function($lis) { + expect($lis).to.have.length(2); + }); + + // Clear item spacing + cy.testJsontext("itemspacing\\(" + "px" + "\\)", ""); + cy.wait(2000); + + // Close property pane + cy.closePropertyPane(); + }); + + it("8. checks button action", function() { // Open property pane - cy.SearchEntityandOpen("Button1"); - cy.testJsontext("label", `{{currentItem.first_name}}`); - cy.addAction("{{currentItem.first_name}}"); + cy.CheckAndUnfoldEntityItem("WIDGETS"); + cy.CheckAndUnfoldEntityItem("List1"); + cy.CheckAndUnfoldEntityItem("Container1"); + cy.selectEntityByName("Button1"); + //cy.SearchEntityandOpen("Button1"); + cy.testJsontext("label", `{{currentItem.last_name}}`); + cy.addAction("{{currentItem.last_name}}"); cy.PublishtheApp(); // Verify Widget Button by clicking on it @@ -84,14 +120,15 @@ describe("Container Widget Functionality", function() { .first() .click(); // Verify the click on first button - cy.get(commonlocators.toastmsg).contains(items[0].first_name); + cy.get(commonlocators.toastmsg).contains(items[0].last_name); }); - it("it checks onListItem click action", function() { + it("9. it checks onListItem click action", function() { // Verify Clicking on list item shows message of first name cy.get(publishPage.backToEditor).click({ force: true }); // Open property pane - cy.SearchEntityandOpen("List1"); + cy.CheckAndUnfoldEntityItem("WIDGETS"); + cy.selectEntityByName("List1"); // Verify Action type and Message of List Item cy.addAction("{{currentItem.first_name}}"); @@ -104,39 +141,35 @@ describe("Container Widget Functionality", function() { cy.get(commonlocators.toastmsg).contains(items[0].first_name); }); - it("it checks pagination", function() { + it("10. it checks pagination", function() { // clicking on second pagination button cy.get(`${commonlocators.paginationButton}-2`).click(); // now we are on the second page which shows first the 3rd item in the list cy.get(commonlocators.TextInside).then(function($lis) { expect($lis.eq(0)).to.contain(items[2].first_name); + expect($lis.eq(1)).to.contain(items[3].first_name); }); cy.get(publishPage.backToEditor).click({ force: true }); }); - it("Chart-Copy Verification", function() { + it("11. ListWidget-Copy & Delete Verification", function() { const modifierKey = Cypress.platform === "darwin" ? "meta" : "ctrl"; //Copy Chart and verify all properties - cy.SearchEntityandOpen("List1"); + cy.CheckAndUnfoldEntityItem("WIDGETS"); + cy.selectEntityByName("List1"); cy.copyWidget("List1Copy", commonlocators.containerWidget); - - // cy.PublishtheApp(); - }); - - it("Chart-Delete Verification", function() { - // Delete the Chart widget - cy.SearchEntityandOpen("List1Copy"); cy.deleteWidget(); cy.PublishtheApp(); - // Verify the cart is deleted - cy.get(commonlocators.containerWidget).should("not.exist"); + // Verify the copied list widget is deleted + cy.get(commonlocators.containerWidget).should("have.length", 2); cy.get(publishPage.backToEditor).click({ force: true }); }); - it("List widget background colour and deploy ", function() { + it("12. List widget background colour and deploy ", function() { // Open Property pane - cy.SearchEntityandOpen("List1"); + cy.CheckAndUnfoldEntityItem("WIDGETS"); + cy.selectEntityByName("List1"); // Scroll down to Styles and Add background colour cy.selectColor("backgroundcolor"); cy.wait(1000); @@ -158,9 +191,10 @@ describe("Container Widget Functionality", function() { cy.get(publishPage.backToEditor).click({ force: true }); }); - it("Toggle JS - List widget background colour and deploy ", function() { + it("13. Toggle JS - List widget background colour and deploy ", function() { // Open Property pane - cy.SearchEntityandOpen("List1"); + cy.CheckAndUnfoldEntityItem("WIDGETS"); + cy.selectEntityByName("List1"); // Scroll down to Styles and Add background colour cy.get(widgetsPage.backgroundColorToggle).click({ force: true }); cy.testJsontext("backgroundcolor", "#FFC13D"); @@ -184,9 +218,10 @@ describe("Container Widget Functionality", function() { cy.get(publishPage.backToEditor).click({ force: true }); }); - it("Add new item in the list widget array object", function() { + it("14. Add new item in the list widget array object", function() { // Open Property pane - cy.SearchEntityandOpen("List1"); + cy.CheckAndUnfoldEntityItem("WIDGETS"); + cy.selectEntityByName("List1"); //Add the new item in the list cy.testJsontext("items", JSON.stringify(this.data.ListItems)); cy.wait(2000); @@ -194,9 +229,10 @@ describe("Container Widget Functionality", function() { cy.get(publishPage.backToEditor).click({ force: true }); }); - it("Adding large item Spacing for item card", function() { + it("15. Adding large item Spacing for item card", function() { // Open Property pane - cy.SearchEntityandOpen("List1"); + cy.CheckAndUnfoldEntityItem("WIDGETS"); + cy.selectEntityByName("List1"); // Scroll down to Styles and Add item spacing for item card cy.testJsontext("itemspacing\\(" + "px" + "\\)", 12); cy.wait(2000); @@ -205,9 +241,10 @@ describe("Container Widget Functionality", function() { cy.get(publishPage.backToEditor).click({ force: true }); }); - it("Renaming the widget from Property pane and Entity explorer ", function() { + it("16. Renaming the widget from Property pane and Entity explorer ", function() { // Open Property pane - cy.SearchEntityandOpen("List1"); + cy.CheckAndUnfoldEntityItem("WIDGETS"); + cy.selectEntityByName("List1"); // Change the list widget name from property pane and Verify it cy.widgetText( "List2", diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Omnibar/Omnibar_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Omnibar/Omnibar_spec.js new file mode 100644 index 0000000000..08a8eb2e09 --- /dev/null +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Omnibar/Omnibar_spec.js @@ -0,0 +1,179 @@ +const omnibar = require("../../../../locators/Omnibar.json"); +const dsl = require("../../../../fixtures/omnibarDsl.json"); +const commonlocators = require("../../../../locators/commonlocators.json"); + +describe("Omnibar functionality test cases", () => { + const apiName = "Omnibar1"; + const jsObjectName = "Omnibar2"; + + before(() => { + cy.addDsl(dsl); + }); + + it("Verify omnibar is present across all pages and validate its fields", function() { + cy.get(omnibar.globalSearch) + .trigger("mouseover") + .should("have.css", "background-color", "rgb(240, 240, 240)"); + cy.get(omnibar.globalSearch).click({ force: true }); + // verifying all sections are present in omnibar + cy.get(omnibar.categoryTitle) + .eq(0) + .should("have.text", "Navigate") + .next() + .should( + "have.text", + "Navigate to any page, widget or file across this project.", + ); + cy.get(omnibar.categoryTitle) + .eq(1) + .should("have.text", "Create New") + .next() + .should("have.text", "Create a new Query, API or JS Object"); + cy.get(omnibar.categoryTitle) + .eq(2) + .should("have.text", "Use Snippets") + .next() + .should( + "have.text", + "Search and insert code snippets to perform complex actions quickly.", + ); + cy.get(omnibar.categoryTitle) + .eq(3) + .should("have.text", "Search Documentation") + .next() + .should("have.text", "Find answers through Appsmith documentation."); + }); + + it("Verify when user clicks on a debugging error, related documentation should open in omnibar", function() { + cy.get(omnibar.globalSearch).click({ force: true }); + // click on debugger icon + cy.get(commonlocators.debugger) + .should("be.visible") + .click({ force: true }); + cy.get(commonlocators.errorTab) + .should("be.visible") + .click({ force: true }); + cy.wait(500); + // click on open documention from error tab + cy.get(commonlocators.debuggerContextMenu).click({ multiple: true }); + cy.xpath(commonlocators.openDocumentationfromErrorTab) + .first() + .click({ force: true }); + // verify omnibar is opened with relevant documentation + cy.wait(500); + cy.get(omnibar.globalSearchInput).should( + "have.value", + "This value does not evaluate to type string", + ); + cy.get(omnibar.globalSearchClose).click(); + }); + + it("Verify Create New section and its data, also create a new api, new js object and new cURL import from omnibar ", function() { + cy.intercept("POST", "/api/v1/actions").as("createNewApi"); + cy.intercept("POST", "/api/v1/collections/actions").as( + "createNewJSCollection", + ); + cy.get(omnibar.categoryTitle) + .eq(1) + .click(); + // create new api, js object and cURL import from omnibar + cy.get(omnibar.createNew) + .eq(0) + .should("have.text", "New Blank API"); + cy.get(omnibar.createNew) + .eq(1) + .should("have.text", "New JS Object"); + cy.get(omnibar.createNew) + .eq(2) + .should("have.text", "New cURL Import"); + cy.get(omnibar.createNew) + .eq(0) + .click(); + cy.wait(1000); + cy.wait("@createNewApi"); + cy.renameWithInPane(apiName); + cy.get(omnibar.globalSearch).click({ force: true }); + cy.get(omnibar.categoryTitle) + .eq(1) + .click(); + cy.get(omnibar.createNew) + .eq(1) + .click(); + cy.wait(1000); + cy.wait("@createNewJSCollection"); + cy.wait(1000); + cy.get(".t--js-action-name-edit-field").type(jsObjectName); + cy.get(omnibar.globalSearch).click({ force: true }); + cy.get(omnibar.categoryTitle) + .eq(1) + .click(); + cy.get(omnibar.createNew) + .eq(2) + .click(); + cy.wait(1000); + cy.xpath("//p[text()='Import from CURL']").should("be.visible"); + }); + + it("Verify on an invalid search, discord link should be displayed and on clicking that link, should open discord in new tab", function() { + // typing a random string in search bar + cy.get(omnibar.globalSearch).click({ force: true }); + cy.wait(1000); + cy.get(omnibar.globalSearchInput).type("vnjkv"); + cy.wait(2000); + cy.get(omnibar.globalSearchInput).should("have.value", "vnjkv"); + // discord link should be visible + cy.get(omnibar.discordLink).should("be.visible"); + cy.window().then((win) => { + cy.stub(win, "open", (url) => { + win.location.href = "https://discord.com/invite/rBTTVJp"; + }).as("discordLink"); + }); + // clicking on discord link should open discord in new tab + cy.get(omnibar.discordLink).click(); + cy.get("@discordLink").should("be.called"); + cy.wait(500); + cy.go(-1); + cy.wait(2000); + }); + + it("Verify Navigate section shows recently opened widgets and datasources", function() { + cy.get(".bp3-icon-chevron-left").click({ force: true }); + cy.openPropertyPane("buttonwidget"); + cy.get(omnibar.globalSearch).click({ force: true }); + cy.get(omnibar.categoryTitle) + .eq(0) + .click(); + // verify recently opened items with their subtext i.e page name + cy.xpath(omnibar.recentlyopenItem) + .eq(0) + .should("have.text", "Button1") + .next() + .should("have.text", "Page1"); + cy.xpath(omnibar.recentlyopenItem) + .eq(2) + .should("have.text", "Omnibar2") + .next() + .should("have.text", "Page1"); + cy.xpath(omnibar.recentlyopenItem) + .eq(3) + .should("have.text", "Omnibar1") + .next() + .should("have.text", "Page1"); + }); + + // commenting this test until the bug #11953 is fixed + /*it("Verify documentation should open in new tab, on clicking on open documentation", function() { + // commenting this test until the bug #11953 is fixed + cy.window().then((win) => { + cy.stub(win, "open", (url) => { + win.location.href = "https://docs.appsmith.com/"; + }).as("documentationLink"); + }); + cy.get(omnibar.categoryTitle) + .eq(3) + .click({ force: true }); + cy.get(omnibar.openDocumentationLink).click(); + cy.get("@documentationLink").should("be.called"); + cy.go(-1); + }); */ +}); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/OrganisationTests/OrgImportApplication_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/OrganisationTests/OrgImportApplication_spec.js index 50f0cc67e1..4408002d45 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/OrganisationTests/OrgImportApplication_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/OrganisationTests/OrgImportApplication_spec.js @@ -10,7 +10,7 @@ describe("Organization Import Application", function() { cy.addDsl(dsl); }); - it("Can Import Application", function() { + it("Can Import Application from json", function() { cy.NavigateToHome(); appname = localStorage.getItem("AppName"); cy.get(homePage.searchInput).type(appname); @@ -47,20 +47,24 @@ describe("Organization Import Application", function() { cy.get(homePage.orgImportAppModal).should("be.visible"); cy.xpath(homePage.uploadLogo).attachFile("exported-app.json"); - cy.get(homePage.orgImportAppButton).click({ force: true }); cy.wait("@importNewApplication").then((interception) => { - let appId = interception.response.body.data.id; - let defaultPage = interception.response.body.data.pages.find( - (eachPage) => !!eachPage.isDefault, - ); + const importedApp = interception.response.body.data.application; + const { pages } = importedApp; + const appSlug = importedApp.slug; + let defaultPage = pages.find((eachPage) => eachPage.isDefault); cy.get(homePage.toastMessage).should( "contain", "Application imported successfully", ); - cy.url().should( - "include", - `/applications/${appId}/pages/${defaultPage.id}/edit`, - ); + cy.wait("@getPagesForCreateApp").then((interception) => { + const pages = interception.response.body.data.pages; + const pageSlug = + pages.find((page) => page.isDefault)?.slug ?? "page"; + cy.url().should( + "include", + `/${appSlug}/${pageSlug}-${defaultPage.id}`, + ); + }); }); }); }); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Pages/Hide_Page_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Pages/Hide_Page_spec.js index 7d7effd55a..01b4f20686 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Pages/Hide_Page_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Pages/Hide_Page_spec.js @@ -6,14 +6,14 @@ const pageTwo = "MyPage2"; describe("Hide / Show page test functionality", function() { it("Hide page test ", function() { - cy.wait(30000); cy.Createpage(pageOne); cy.Createpage(pageTwo); cy.get(".t--entity-name") .contains("Page1") .click({ force: true }); - cy.get(`.t--entity-name:contains('MyPage2')`).trigger("mouseover"); - cy.hoverAndClick(); + cy.get(`.t--entity-item:contains('MyPage2')`).within(() => { + cy.get(".t--context-menu").click({ force: true }); + }); cy.get(pages.hidePage).click({ force: true }); cy.ClearSearch(); cy.PublishtheApp(); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Pages/Page_Load_Spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Pages/Page_Load_Spec.js index d8bcc07793..f18cf8ac9f 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Pages/Page_Load_Spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Pages/Page_Load_Spec.js @@ -1,6 +1,5 @@ const dsl = require("../../../../fixtures/PageLoadDsl.json"); const commonlocators = require("../../../../locators/commonlocators.json"); -const pages = require("../../../../locators/Pages.json"); const publish = require("../../../../locators/publishWidgetspage.json"); const explorerLocators = require("../../../../locators/explorerlocators.json"); @@ -15,7 +14,8 @@ describe("Page Load tests", () => { cy.get("h2").contains("Drag and drop a widget here"); }); - it("Published page loads correctly", () => { + + it("1. Published page loads correctly", () => { //add page within page cy.addDsl(dsl); // Update the text to be asserted later @@ -30,6 +30,8 @@ describe("Page Load tests", () => { .parent() .parent() .parent() + .parent() + .parent() .should("have.class", "is-active"); // Assert active page DSL cy.get(commonlocators.headingTextStyle).should( @@ -45,6 +47,8 @@ describe("Page Load tests", () => { .parent() .parent() .parent() + .parent() + .parent() .should("have.class", "is-active"); // Assert active page DSL cy.get(commonlocators.headingTextStyle).should( @@ -62,6 +66,8 @@ describe("Page Load tests", () => { .parent() .parent() .parent() + .parent() + .parent() .should("have.class", "is-active"); // Assert active page DSL cy.get(commonlocators.headingTextStyle).should( @@ -70,20 +76,17 @@ describe("Page Load tests", () => { ); }); - it.skip("Hide Page and validate published app", () => { + it("2. Hide Page and validate published app", () => { cy.get(publish.backToEditor).click(); - cy.GlobalSearchEntity("Page1"); - cy.xpath(pages.popover) - .last() - .click({ force: true }); - cy.get(pages.hidePage).click({ force: true }); - cy.ClearSearch(); + cy.actionContextMenuByEntityName("Page1", "Hide"); cy.PublishtheApp(); // Assert active page DSL cy.get(commonlocators.headingTextStyle).should( "have.text", "This is Page 1", ); + cy.contains("Page2").should("not.exist"); + cy.get(publish.backToEditor).click(); cy.SearchEntityandOpen("Page2"); cy.PublishtheApp(); @@ -92,5 +95,6 @@ describe("Page Load tests", () => { "have.text", "This is Page 2", ); + cy.contains("Page1").should("not.exist"); }); }); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/QueryPaneTests/Datasourcedocs_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/QueryPaneTests/Datasourcedocs_spec.js index 01141b30e3..e27254d0c2 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/QueryPaneTests/Datasourcedocs_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/QueryPaneTests/Datasourcedocs_spec.js @@ -39,13 +39,7 @@ describe("Check datasource doc links", function() { }); it("3. Delete the query and datasources", function() { - cy.get(queryEditor.queryMoreAction).click(); - cy.get(queryEditor.deleteUsingContext).click(); - cy.wait("@deleteAction").should( - "have.nested.property", - "response.body.responseMeta.status", - 200, - ); + cy.deleteQueryUsingContext(); cy.deleteDatasource(postgresDatasourceName); }); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/QueryPaneTests/SwitchDatasource_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/QueryPaneTests/SwitchDatasource_spec.js index bbd497d88e..e1a8717cf4 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/QueryPaneTests/SwitchDatasource_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/QueryPaneTests/SwitchDatasource_spec.js @@ -78,13 +78,7 @@ describe("Switch datasource", function() { }); it("4. Delete the query and datasources", function() { - cy.get(queryEditor.queryMoreAction).click(); - cy.get(queryEditor.deleteUsingContext).click(); - cy.wait("@deleteAction").should( - "have.nested.property", - "response.body.responseMeta.status", - 200, - ); + cy.deleteQueryUsingContext(); cy.deleteDatasource(postgresDatasourceName); cy.deleteDatasource(mongoDatasourceName); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Replay/Replay_Editor_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Replay/Replay_Editor_spec.js index b9e99297c6..e0099ecbca 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Replay/Replay_Editor_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Replay/Replay_Editor_spec.js @@ -29,7 +29,10 @@ describe("Undo/Redo functionality", function() { cy.get(datasourceEditor.password).type( datasourceFormData["postgres-password"], ); - cy.get(datasourceEditor.sectionAuthentication).click(); + cy.get(datasourceEditor.sectionAuthentication) + .trigger("click") + .wait(1000); + cy.get("body").type(`{${modifierKey}}z`); cy.get( `${datasourceEditor.sectionAuthentication} .bp3-icon-chevron-up`, @@ -40,6 +43,7 @@ describe("Undo/Redo functionality", function() { .trigger("mouseover"); cy.get("li:contains(Undo)").click({ multiple: true }); cy.get(datasourceEditor.username).should("be.empty"); + cy.get(datasourceEditor.saveBtn).click({ force: true }); }); it("Checks undo/redo for Api pane", function() { diff --git a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/ApiFlow/CurlImportFlow_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/ApiFlow/CurlImportFlow_spec.js index 8d0cf125c2..c9753776ed 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/ApiFlow/CurlImportFlow_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/ApiFlow/CurlImportFlow_spec.js @@ -25,8 +25,13 @@ describe("Test curl import flow", function() { cy.RunAPI(); cy.ResponseStatusCheck("200 OK"); cy.get(ApiEditor.formActionButtons).should("be.visible"); - cy.get(ApiEditor.ApiActionMenu).click(); + cy.get(ApiEditor.ApiActionMenu) + .first() + .click(); cy.get(ApiEditor.ApiDeleteBtn).click(); + cy.get(ApiEditor.ApiDeleteBtn) + .contains("Are you sure?") + .click(); cy.wait("@deleteAction"); cy.get("@deleteAction").then((response) => { cy.expect(response.response.body.responseMeta.success).to.eq(true); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/ApiPaneTests/API_All_Verb_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/ApiPaneTests/API_All_Verb_spec.js index a4f9be8249..4d44bf0c0d 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/ApiPaneTests/API_All_Verb_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/ApiPaneTests/API_All_Verb_spec.js @@ -4,8 +4,11 @@ import ApiEditor from "../../../../locators/ApiEditor"; describe("API Panel Test Functionality", function() { afterEach(function() { - cy.get(ApiEditor.ApiActionMenu).click({ force: true }); + cy.get(ApiEditor.ApiActionMenu).click({ multiple: true }); cy.get(apiwidget.deleteAPI).click({ force: true }); + cy.get(apiwidget.deleteAPI) + .contains("Are you sure?") + .click({ force: true }); cy.wait("@deleteAction").should( "have.nested.property", "response.body.responseMeta.status", diff --git a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/ApiPaneTests/API_Bugs_Spec.js b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/ApiPaneTests/API_Bugs_Spec.js index f9cdb9f0e2..674e8ab21e 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/ApiPaneTests/API_Bugs_Spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/ApiPaneTests/API_Bugs_Spec.js @@ -5,14 +5,17 @@ const pages = require("../../../../locators/Pages.json"); const testdata = require("../../../../fixtures/testdata.json"); describe("Rest Bugs tests", function() { - it("Bug 5550: Not able to run APIs in parallel", function() { + //Skipping until api endpoint fixed + it.skip("Bug 5550: Not able to run APIs in parallel", function() { cy.addDsl(dslParallel); + cy.wait(5000); //settling time for dsl! + cy.get(".bp3-spinner").should("not.exist"); //Api 1 cy.NavigateToAPI_Panel(); cy.CreateAPI("CatImage"); cy.enterDatasource("https://api.thecatapi.com/v1/images/search"); - cy.wait(1000); + cy.assertPageSave(); cy.get("body").click(0, 0); //Api 2 @@ -21,14 +24,16 @@ describe("Rest Bugs tests", function() { cy.enterDatasource( "https://cat-fact.herokuapp.com/facts/random?animal_type=cat", ); - cy.wait(1000); + cy.assertPageSave(); + cy.get("body").click(0, 0); //Api 3 cy.NavigateToAPI_Panel(); cy.CreateAPI("DogImage"); cy.enterDatasource("https://dog.ceo/api/breeds/image/random"); - cy.wait(1000); //important - needed for autosave of API before running + cy.assertPageSave(); + //important - needed for autosave of API before running cy.get("body").click(0, 0); //Api 4 @@ -37,7 +42,7 @@ describe("Rest Bugs tests", function() { cy.enterDatasource( "https://cat-fact.herokuapp.com/facts/random?animal_type=dog", ); - cy.wait(1000); + cy.assertPageSave(); cy.get("body").click(0, 0); cy.contains(commonlocators.entityName, "Page1").click({ force: true }); @@ -116,6 +121,8 @@ describe("Rest Bugs tests", function() { it("Bug 4775: No Cyclical dependency when Api returns an error", function() { cy.addDsl(dslTable); + cy.wait(5000); //settling time for dsl! + cy.get(".bp3-spinner").should("not.exist"); //Api 1 cy.CreateAPI("Currencies"); cy.enterDatasource("https://api.coinbase.com/v2/currencies"); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/Datasources/ArangoDataSourceStub_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/Datasources/ArangoDataSourceStub_spec.js index e4ffacf683..f81616abc0 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/Datasources/ArangoDataSourceStub_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/Datasources/ArangoDataSourceStub_spec.js @@ -54,13 +54,7 @@ describe("Arango datasource test cases", function() { 201, ); - cy.get(queryEditor.queryMoreAction).click(); - cy.get(queryEditor.deleteUsingContext).click(); - cy.wait("@deleteAction").should( - "have.nested.property", - "response.body.responseMeta.status", - 200, - ); + cy.deleteQueryUsingContext(); cy.deleteDatasource(datasourceName); }); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/Datasources/AuthenticatedApiDatasource_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/Datasources/AuthenticatedApiDatasource_spec.js index 4656a7682b..9dfcaa9bc0 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/Datasources/AuthenticatedApiDatasource_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/Datasources/AuthenticatedApiDatasource_spec.js @@ -1,4 +1,5 @@ const apiwidget = require("../../../../locators/apiWidgetslocator.json"); +const datasourceFormData = require("../../../../fixtures/datasources.json"); describe("Authenticated API Datasource", function() { it("Can create New Authentication API datasource", function() { @@ -9,5 +10,9 @@ describe("Authenticated API Datasource", function() { "response.body.responseMeta.status", 201, ); + cy.fillAuthenticatedAPIForm(); + cy.saveDatasource(); + const URL = datasourceFormData["authenticatedApiUrl"]; + cy.contains(URL); }); }); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/Datasources/DatasourceForm_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/Datasources/DatasourceForm_spec.js index 3f004e87c7..5a2842864a 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/Datasources/DatasourceForm_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/Datasources/DatasourceForm_spec.js @@ -28,7 +28,7 @@ describe("Datasource form related tests", function() { .trigger("mouseover"); cy.hoverAndClickParticularIndex(1); cy.get('.single-select:contains("Copy to page")').click(); - cy.get('.single-select:contains("Page1")').click(); + cy.get('.single-select:contains("Page1")').click({ force: true }); cy.validateToastMessage("Testapi action copied to page Page1 successfully"); }); }); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/Datasources/MsSQLDataSourceStub_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/Datasources/MsSQLDataSourceStub_spec.js index d95dffd180..06eaeae2a4 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/Datasources/MsSQLDataSourceStub_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/Datasources/MsSQLDataSourceStub_spec.js @@ -54,13 +54,7 @@ describe("MsSQL datasource test cases", function() { 201, ); - cy.get(queryEditor.queryMoreAction).click(); - cy.get(queryEditor.deleteUsingContext).click(); - cy.wait("@deleteAction").should( - "have.nested.property", - "response.body.responseMeta.status", - 200, - ); + cy.deleteQueryUsingContext(); cy.deleteDatasource(datasourceName); }); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/Datasources/MySQLDataSourceStub_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/Datasources/MySQLDataSourceStub_spec.js index 74e058d297..ed32425eed 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/Datasources/MySQLDataSourceStub_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/Datasources/MySQLDataSourceStub_spec.js @@ -54,13 +54,7 @@ describe("MySQL datasource test cases", function() { 201, ); - cy.get(queryEditor.queryMoreAction).click(); - cy.get(queryEditor.deleteUsingContext).click(); - cy.wait("@deleteAction").should( - "have.nested.property", - "response.body.responseMeta.status", - 200, - ); + cy.deleteQueryUsingContext(); cy.deleteDatasource(datasourceName); }); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/Datasources/MySQL_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/Datasources/MySQL_spec.js index ea1b10eb59..5e09293be5 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/Datasources/MySQL_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/Datasources/MySQL_spec.js @@ -42,13 +42,7 @@ describe("MySQL datasource test cases", function() { 201, ); - cy.get(queryEditor.queryMoreAction).click(); - cy.get(queryEditor.deleteUsingContext).click(); - cy.wait("@deleteAction").should( - "have.nested.property", - "response.body.responseMeta.status", - 200, - ); + cy.deleteQueryUsingContext(); cy.deleteDatasource(datasourceName); }); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/Datasources/PostgresDatasource_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/Datasources/PostgresDatasource_spec.js index c4a51ab1b8..a635a6f8e0 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/Datasources/PostgresDatasource_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/Datasources/PostgresDatasource_spec.js @@ -42,13 +42,7 @@ describe("Postgres datasource test cases", function() { 201, ); - cy.get(queryEditor.queryMoreAction).click(); - cy.get(queryEditor.deleteUsingContext).click(); - cy.wait("@deleteAction").should( - "have.nested.property", - "response.body.responseMeta.status", - 200, - ); + cy.deleteQueryUsingContext(); cy.deleteDatasource(datasourceName); }); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/Datasources/RedshiftDataSourceStub_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/Datasources/RedshiftDataSourceStub_spec.js index 6df8dbddf6..a3ac7ecbd8 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/Datasources/RedshiftDataSourceStub_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/Datasources/RedshiftDataSourceStub_spec.js @@ -54,13 +54,7 @@ describe("Redshift datasource test cases", function() { 201, ); - cy.get(queryEditor.queryMoreAction).click(); - cy.get(queryEditor.deleteUsingContext).click(); - cy.wait("@deleteAction").should( - "have.nested.property", - "response.body.responseMeta.status", - 200, - ); + cy.deleteQueryUsingContext(); cy.deleteDatasource(datasourceName); }); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/Datasources/SMTPDatasource_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/Datasources/SMTPDatasource_spec.js index 79e0c0dc7d..b7903d781b 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/Datasources/SMTPDatasource_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/Datasources/SMTPDatasource_spec.js @@ -85,6 +85,7 @@ describe("SMTP datasource test cases using ted", function() { ); }); }); + /* it("3. On canvas, fill to email, from email, subject, body, attachment and run query", function() { cy.get(`.t--entity-name:contains("smtpquery")`) .should("be.visible") diff --git a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/ExplorerTests/EditorContextMenu_Spec.ts b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/ExplorerTests/EditorContextMenu_Spec.ts index 31bebf6a47..dd8702c3f7 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/ExplorerTests/EditorContextMenu_Spec.ts +++ b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/ExplorerTests/EditorContextMenu_Spec.ts @@ -9,6 +9,7 @@ describe("Validate basic operations on Entity explorer JSEditor structure", () = it("1. Validate JSObject creation & Run", () => { jsEditor.CreateJSObject('return "Hello World";'); + agHelper.expandCollapseEntity("QUERIES/JS"); agHelper.ValidateEntityPresenceInExplorer("JSObject1"); jsEditor.validateDefaultJSObjProperties("JSObject1"); }); @@ -45,7 +46,7 @@ describe("Validate basic operations on Entity explorer JSEditor structure", () = agHelper.AddNewPage(); agHelper.ValidateEntityPresenceInExplorer(newPageId); agHelper.SelectEntityByName(pageId); - cy.CheckAndUnfoldEntityItem("QUERIES/JS"); + agHelper.expandCollapseEntity("QUERIES/JS"); agHelper.ActionContextMenuByEntityName( "RenamedJSObjectCopy", "Move to page", @@ -58,8 +59,12 @@ describe("Validate basic operations on Entity explorer JSEditor structure", () = it("6. Validate Deletion of JSObject", function() { agHelper.SelectEntityByName(pageId); - cy.CheckAndUnfoldEntityItem("QUERIES/JS"); - agHelper.ActionContextMenuByEntityName("ExplorerRenamed", "Delete"); + agHelper.expandCollapseEntity("QUERIES/JS"); + agHelper.ActionContextMenuByEntityName( + "ExplorerRenamed", + "Delete", + "Are you sure?", + ); agHelper.ValidateEntityAbsenceInExplorer("ExplorerRenamed"); }); }); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/ExplorerTests/Entity_Explorer_CopyQuery_RenameDatasource_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/ExplorerTests/Entity_Explorer_CopyQuery_RenameDatasource_spec.js index 943cd0e179..79f5a4c62c 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/ExplorerTests/Entity_Explorer_CopyQuery_RenameDatasource_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/ExplorerTests/Entity_Explorer_CopyQuery_RenameDatasource_spec.js @@ -1,8 +1,6 @@ const queryLocators = require("../../../../locators/QueryEditor.json"); const datasource = require("../../../../locators/DatasourcesEditor.json"); const apiwidget = require("../../../../locators/apiWidgetslocator.json"); -const commonlocators = require("../../../../locators/commonlocators.json"); -const explorer = require("../../../../locators/explorerlocators.json"); import { AggregateHelper } from "../../../../support/Pages/AggregateHelper"; const agHelper = new AggregateHelper(); @@ -15,11 +13,17 @@ describe("Entity explorer tests related to copy query", function() { cy.startRoutesForDatasource(); }); - it("1. Create a query with dataSource in explorer", function() { + // afterEach(function() { + // if (this.currentTest.state === "failed") { + // Cypress.runner.stop(); + // } + // }); + + it("1. Create a query with dataSource in explorer, Create new Page", function() { cy.Createpage(pageid); cy.get(".t--entity-name") .contains("Page1") - .click(); + .click({ force: true }); cy.wait(2000); cy.NavigateToDatasourceEditor(); cy.get(datasource.PostgreSQL).click(); @@ -63,10 +67,10 @@ describe("Entity explorer tests related to copy query", function() { }); }); - it("2. Create a page and copy query in explorer", function() { + it("2. Copy query in explorer to new page & verify Bindings are copied too", function() { cy.get(".t--entity-name") .contains("Page1") - .click(); + .click({ force: true }); agHelper.ActionContextMenuByEntityName("Query1", "Copy to page", pageid); cy.CheckAndUnfoldEntityItem("QUERIES/JS"); cy.get(".t--entity-name") @@ -83,10 +87,10 @@ describe("Entity explorer tests related to copy query", function() { }); }); - it("3. Delete query and rename datasource in explorer", function() { + it("3. Rename datasource in explorer, Delete query and try to Delete datasource", function() { cy.get(".t--entity-name") .contains("Page1") - .click(); + .click({ force: true }); cy.wait(2000); cy.generateUUID().then((uid) => { updatedName = uid; @@ -95,10 +99,13 @@ describe("Entity explorer tests related to copy query", function() { cy.log("sliced id :" + updatedName); cy.CheckAndUnfoldEntityItem("QUERIES/JS"); cy.EditEntityNameByDoubleClick(datasourceName, updatedName); - cy.wait(2000); - cy.hoverAndClick(); - cy.get(apiwidget.delete).click({ force: true }); - cy.get("[data-cy=t--confirm-modal-btn]").click(); + cy.wait(1000); + agHelper.ActionContextMenuByEntityName( + updatedName, + "Delete", + "Are you sure?", + ); + cy.wait(1000); //This is check to make sure if a datasource is active 409 cy.wait("@deleteDatasource").should( "have.nested.property", @@ -106,10 +113,9 @@ describe("Entity explorer tests related to copy query", function() { 409, ); }); - cy.get(".t--entity-name") .contains("Query1") .click(); - agHelper.ActionContextMenuByEntityName("Query1", "Delete"); + agHelper.ActionContextMenuByEntityName("Query1", "Delete", "Are you sure?"); }); }); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/ExplorerTests/Entity_Explorer_Datasource_Structure_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/ExplorerTests/Entity_Explorer_Datasource_Structure_spec.js index 167c6f46f4..867be76269 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/ExplorerTests/Entity_Explorer_Datasource_Structure_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/ExplorerTests/Entity_Explorer_Datasource_Structure_spec.js @@ -62,24 +62,12 @@ describe("Entity explorer datasource structure", function() { 201, ); - cy.get(queryEditor.queryMoreAction).click(); - cy.get(queryEditor.deleteUsingContext).click(); - cy.wait("@deleteAction").should( - "have.nested.property", - "response.body.responseMeta.status", - 200, - ); + cy.deleteQueryUsingContext(); cy.CheckAndUnfoldEntityItem("QUERIES/JS"); cy.GlobalSearchEntity("MyQuery"); cy.get(`.t--entity-name:contains(MyQuery)`).click(); - cy.get(queryEditor.queryMoreAction).click(); - cy.get(queryEditor.deleteUsingContext).click(); - cy.wait("@deleteAction").should( - "have.nested.property", - "response.body.responseMeta.status", - 200, - ); + cy.deleteQueryUsingContext(); cy.get(commonlocators.entityExplorersearch).clear({ force: true }); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/LayoutOnLoadActions/OnLoadActions_Spec.ts b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/LayoutOnLoadActions/OnLoadActions_Spec.ts index 9f88bc259d..81acdbeefd 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/LayoutOnLoadActions/OnLoadActions_Spec.ts +++ b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/LayoutOnLoadActions/OnLoadActions_Spec.ts @@ -6,132 +6,172 @@ const apiPage = new ApiPage(); const agHelper = new AggregateHelper(); const homePage = new HomePage(); -describe("Layout OnLoad Actions tests", function () { - let dsl: any; - before(() => { - cy.fixture('onPageLoadActionsDsl').then((val: any) => { - dsl = val; - }); +describe("Layout OnLoad Actions tests", function() { + let dsl: any; + before(() => { + cy.fixture("onPageLoadActionsDsl").then((val: any) => { + dsl = val; }); + }); - it("1. Bug 8595: OnPageLoad execution - when No api to run on Pageload", function () { - agHelper.AddDsl(dsl) - agHelper.SelectEntityByName('WIDGETS') - agHelper.SelectEntityByName('Page1') - cy.url().then((url) => { - let currentURL = url; - const myRegexp = /pages(.*)/; - const match = myRegexp.exec(currentURL); - let pageid = match![1].split("/")[1]; - cy.log(pageid + "page id"); - cy.request("GET", "api/v1/pages/" + pageid).then((response) => { - const respBody = JSON.stringify(response.body); - let _emptyResp = JSON.parse(respBody).data.layouts[0].layoutOnLoadActions; - expect(JSON.parse(JSON.stringify(_emptyResp))).to.deep.eq([]) - }); - }); + it("1. Bug 8595: OnPageLoad execution - when No api to run on Pageload", function() { + agHelper.AddDsl(dsl); + agHelper.SelectEntityByName("WIDGETS"); + agHelper.SelectEntityByName("Page1"); + cy.url().then((url) => { + const pageid = url.split("/")[4]?.split("-").pop(); + cy.log(pageid + "page id"); + cy.request("GET", "api/v1/pages/" + pageid).then((response) => { + const respBody = JSON.stringify(response.body); + const _emptyResp = JSON.parse(respBody).data.layouts[0] + .layoutOnLoadActions; + expect(JSON.parse(JSON.stringify(_emptyResp))).to.deep.eq([]); + }); }); + }); - it("2. Bug 8595: OnPageLoad execution - when Query Parmas added via Params tab", function () { - agHelper.AddDsl(dsl) - apiPage.CreateAndFillApi("https://source.unsplash.com/collection/1599413", "RandomFlora") - apiPage.RunAPI() + it("2. Bug 8595: OnPageLoad execution - when Query Parmas added via Params tab", function() { + agHelper.AddDsl(dsl); + apiPage.CreateAndFillApi( + "https://source.unsplash.com/collection/1599413", + "RandomFlora", + ); + apiPage.RunAPI(); - apiPage.CreateAndFillApi("https://randomuser.me/api/", "RandomUser") - apiPage.RunAPI() + apiPage.CreateAndFillApi("https://randomuser.me/api/", "RandomUser"); + apiPage.RunAPI(); - apiPage.CreateAndFillApi("https://favqs.com/api/qotd", "InspiringQuotes") - apiPage.EnterHeader('dependency', '{{RandomUser.data}}') - apiPage.RunAPI() + apiPage.CreateAndFillApi("https://favqs.com/api/qotd", "InspiringQuotes"); + apiPage.EnterHeader("dependency", "{{RandomUser.data}}"); + apiPage.RunAPI(); - apiPage.CreateAndFillApi("https://www.boredapi.com/api/activity", "Suggestions") - apiPage.EnterHeader('dependency', '{{InspiringQuotes.data}}') - apiPage.RunAPI() + apiPage.CreateAndFillApi( + "https://www.boredapi.com/api/activity", + "Suggestions", + ); + apiPage.EnterHeader("dependency", "{{InspiringQuotes.data}}"); + apiPage.RunAPI(); - apiPage.CreateAndFillApi("https://api.genderize.io", "Genderize") - apiPage.EnterParams('name', '{{RandomUser.data.results[0].name.first}}') - apiPage.RunAPI() - agHelper.SelectEntityByName('WIDGETS') - agHelper.SelectEntityByName('Page1') + apiPage.CreateAndFillApi("https://api.genderize.io", "Genderize"); + apiPage.EnterParams("name", "{{RandomUser.data.results[0].name.first}}"); + apiPage.RunAPI(); + agHelper.SelectEntityByName("WIDGETS"); + agHelper.SelectEntityByName("Page1"); - cy.url().then((url) => { - let currentURL = url; - const myRegexp = /pages(.*)/; - const match = myRegexp.exec(currentURL); - let pageid = match![1].split("/")[1]; - cy.log(pageid + "page id"); - cy.request("GET", "api/v1/pages/" + pageid).then((response) => { - const respBody = JSON.stringify(response.body); + cy.url().then((url) => { + const pageid = url.split("/")[4]?.split("-").pop(); + cy.log(pageid + "page id"); + cy.request("GET", "api/v1/pages/" + pageid).then((response) => { + const respBody = JSON.stringify(response.body); - let _randomFlora = JSON.parse(respBody).data.layouts[0].layoutOnLoadActions[0]; - let _randomUser = JSON.parse(respBody).data.layouts[0].layoutOnLoadActions[1]; - let _genderize = JSON.parse(respBody).data.layouts[0].layoutOnLoadActions[2]; - let _suggestions = JSON.parse(respBody).data.layouts[0].layoutOnLoadActions[3]; - // cy.log("_randomFlora is: " + JSON.stringify(_randomFlora)) - // cy.log("_randomUser is: " + JSON.stringify(_randomUser)) - // cy.log("_genderize is: " + JSON.stringify(_genderize)) - // cy.log("_suggestions is: " + JSON.stringify(_suggestions)) + const _randomFlora = JSON.parse(respBody).data.layouts[0] + .layoutOnLoadActions[0]; + const _randomUser = JSON.parse(respBody).data.layouts[0] + .layoutOnLoadActions[1]; + const _genderize = JSON.parse(respBody).data.layouts[0] + .layoutOnLoadActions[2]; + const _suggestions = JSON.parse(respBody).data.layouts[0] + .layoutOnLoadActions[3]; + // cy.log("_randomFlora is: " + JSON.stringify(_randomFlora)) + // cy.log("_randomUser is: " + JSON.stringify(_randomUser)) + // cy.log("_genderize is: " + JSON.stringify(_genderize)) + // cy.log("_suggestions is: " + JSON.stringify(_suggestions)) - expect(JSON.parse(JSON.stringify(_randomFlora))[0]['name']).to.eq('RandomFlora') - expect(JSON.parse(JSON.stringify(_randomUser))[0]['name']).to.eq('RandomUser') - expect(JSON.parse(JSON.stringify(_genderize))[0]['name']).to.be.oneOf(['Genderize', 'InspiringQuotes']) - expect(JSON.parse(JSON.stringify(_genderize))[1]['name']).to.be.oneOf(['Genderize', 'InspiringQuotes']) - expect(JSON.parse(JSON.stringify(_suggestions))[0]['name']).to.eq('Suggestions') - - }); - }); + expect(JSON.parse(JSON.stringify(_randomFlora))[0]["name"]).to.eq( + "RandomFlora", + ); + expect(JSON.parse(JSON.stringify(_randomUser))[0]["name"]).to.eq( + "RandomUser", + ); + expect(JSON.parse(JSON.stringify(_genderize))[0]["name"]).to.be.oneOf([ + "Genderize", + "InspiringQuotes", + ]); + expect(JSON.parse(JSON.stringify(_genderize))[1]["name"]).to.be.oneOf([ + "Genderize", + "InspiringQuotes", + ]); + expect(JSON.parse(JSON.stringify(_suggestions))[0]["name"]).to.eq( + "Suggestions", + ); + }); }); + }); - it("3. Bug 10049, 10055: Dependency not executed in expected order in layoutOnLoadActions when dependency added via URL", function () { - homePage.NavigateToHome() - homePage.CreateNewApplication() - agHelper.AddDsl(dsl) + it("3. Bug 10049, 10055: Dependency not executed in expected order in layoutOnLoadActions when dependency added via URL", function() { + homePage.NavigateToHome(); + homePage.CreateNewApplication(); + agHelper.AddDsl(dsl); - apiPage.CreateAndFillApi("https://source.unsplash.com/collection/1599413", "RandomFlora") - apiPage.RunAPI() + apiPage.CreateAndFillApi( + "https://source.unsplash.com/collection/1599413", + "RandomFlora", + ); + apiPage.RunAPI(); - apiPage.CreateAndFillApi("https://randomuser.me/api/", "RandomUser") - apiPage.RunAPI() + apiPage.CreateAndFillApi("https://randomuser.me/api/", "RandomUser"); + apiPage.RunAPI(); - apiPage.CreateAndFillApi("https://favqs.com/api/qotd", "InspiringQuotes") - apiPage.EnterHeader('dependency', '{{RandomUser.data}}') - apiPage.RunAPI() + apiPage.CreateAndFillApi("https://favqs.com/api/qotd", "InspiringQuotes"); + apiPage.EnterHeader("dependency", "{{RandomUser.data}}"); + apiPage.RunAPI(); - apiPage.CreateAndFillApi("https://www.boredapi.com/api/activity", "Suggestions") - apiPage.EnterHeader('dependency', '{{InspiringQuotes.data}}') - apiPage.RunAPI() + apiPage.CreateAndFillApi( + "https://www.boredapi.com/api/activity", + "Suggestions", + ); + apiPage.EnterHeader("dependency", "{{InspiringQuotes.data}}"); + apiPage.RunAPI(); - apiPage.CreateAndFillApi("https://api.genderize.io?name={{RandomUser.data.results[0].name.first}}", "Genderize") - apiPage.ValidateQueryParams({ key: "name", value: "{{RandomUser.data.results[0].name.first}}" }); // verifies Bug 10055 - apiPage.RunAPI() - agHelper.SelectEntityByName('WIDGETS') - agHelper.SelectEntityByName('Page1') + apiPage.CreateAndFillApi( + "https://api.genderize.io?name={{RandomUser.data.results[0].name.first}}", + "Genderize", + ); + apiPage.ValidateQueryParams({ + key: "name", + value: "{{RandomUser.data.results[0].name.first}}", + }); // verifies Bug 10055 + apiPage.RunAPI(); + agHelper.SelectEntityByName("WIDGETS"); + agHelper.SelectEntityByName("Page1"); - cy.url().then((url) => { - let currentURL = url; - const myRegexp = /pages(.*)/; - const match = myRegexp.exec(currentURL); - let pageid = match![1].split("/")[1]; - cy.log(pageid + "page id"); - cy.request("GET", "api/v1/pages/" + pageid).then((response) => { - const respBody = JSON.stringify(response.body); + cy.url().then((url) => { + const pageid = url.split("/")[4]?.split("-").pop(); + cy.log(pageid + "page id"); + cy.request("GET", "api/v1/pages/" + pageid).then((response) => { + const respBody = JSON.stringify(response.body); - let _randomFlora = JSON.parse(respBody).data.layouts[0].layoutOnLoadActions[0]; - let _randomUser = JSON.parse(respBody).data.layouts[0].layoutOnLoadActions[1]; - let _genderize = JSON.parse(respBody).data.layouts[0].layoutOnLoadActions[2]; - let _suggestions = JSON.parse(respBody).data.layouts[0].layoutOnLoadActions[3]; - // cy.log("_randomFlora is: " + JSON.stringify(_randomFlora)) - // cy.log("_randomUser is: " + JSON.stringify(_randomUser)) - // cy.log("_genderize is: " + JSON.stringify(_genderize)) - // cy.log("_suggestions is: " + JSON.stringify(_suggestions)) + const _randomFlora = JSON.parse(respBody).data.layouts[0] + .layoutOnLoadActions[0]; + const _randomUser = JSON.parse(respBody).data.layouts[0] + .layoutOnLoadActions[1]; + const _genderize = JSON.parse(respBody).data.layouts[0] + .layoutOnLoadActions[2]; + const _suggestions = JSON.parse(respBody).data.layouts[0] + .layoutOnLoadActions[3]; + // cy.log("_randomFlora is: " + JSON.stringify(_randomFlora)) + // cy.log("_randomUser is: " + JSON.stringify(_randomUser)) + // cy.log("_genderize is: " + JSON.stringify(_genderize)) + // cy.log("_suggestions is: " + JSON.stringify(_suggestions)) - expect(JSON.parse(JSON.stringify(_randomFlora))[0]['name']).to.eq('RandomFlora') - expect(JSON.parse(JSON.stringify(_randomUser))[0]['name']).to.eq('RandomUser') - expect(JSON.parse(JSON.stringify(_genderize))[0]['name']).to.be.oneOf(['Genderize', 'InspiringQuotes']) - expect(JSON.parse(JSON.stringify(_genderize))[1]['name']).to.be.oneOf(['Genderize', 'InspiringQuotes']) - expect(JSON.parse(JSON.stringify(_suggestions))[0]['name']).to.eq('Suggestions') - - }); - }); + expect(JSON.parse(JSON.stringify(_randomFlora))[0]["name"]).to.eq( + "RandomFlora", + ); + expect(JSON.parse(JSON.stringify(_randomUser))[0]["name"]).to.eq( + "RandomUser", + ); + expect(JSON.parse(JSON.stringify(_genderize))[0]["name"]).to.be.oneOf([ + "Genderize", + "InspiringQuotes", + ]); + expect(JSON.parse(JSON.stringify(_genderize))[1]["name"]).to.be.oneOf([ + "Genderize", + "InspiringQuotes", + ]); + expect(JSON.parse(JSON.stringify(_suggestions))[0]["name"]).to.eq( + "Suggestions", + ); + }); }); -}); \ No newline at end of file + }); +}); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/OrganisationTests/ShareAppTests_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/OrganisationTests/ShareAppTests_spec.js index 0811f8563d..a4f29834b4 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/OrganisationTests/ShareAppTests_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/OrganisationTests/ShareAppTests_spec.js @@ -133,7 +133,7 @@ describe("Create new org and share with a user", function() { it("6. login as uninvited user and then validate public access disable feature", function() { cy.LoginFromAPI(Cypress.env("TESTUSERNAME2"), Cypress.env("TESTPASSWORD2")); cy.visit(currentUrl); - cy.wait("@viewApp").should( + cy.wait("@getPagesForViewApp").should( "have.nested.property", "response.body.responseMeta.status", 404, @@ -143,7 +143,7 @@ describe("Create new org and share with a user", function() { it("7. visit the app as anonymous user and validate redirection to login page", function() { cy.visit(currentUrl); - cy.wait("@viewApp").should( + cy.wait("@getPagesForViewApp").should( "have.nested.property", "response.body.responseMeta.status", 404, diff --git a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/Params/PassingParams_Spec.ts b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/Params/PassingParams_Spec.ts index bfedd19018..94f2d5cade 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/Params/PassingParams_Spec.ts +++ b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/Params/PassingParams_Spec.ts @@ -37,7 +37,7 @@ describe("[Bug] - 10784 - Passing params from JS to SQL query should not break", 'Params1.run(() => {},() => {},{"condition": selRecordFilter.selectedOptionValue})', ); }); - cy.CheckAndUnfoldEntityItem("WIDGETS"); + agHelper.expandCollapseEntity("WIDGETS"); agHelper.SelectEntityByName("Button1"); cy.get("@jsObjName").then((jsObjName) => { jsEditor.EnterJSContext( diff --git a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/QueryPane/ConfirmRunAction_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/QueryPane/ConfirmRunAction_spec.js index 86f55695f4..25ec58ea19 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/QueryPane/ConfirmRunAction_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/QueryPane/ConfirmRunAction_spec.js @@ -29,7 +29,7 @@ describe("Confirm run action", function() { cy.onlyQueryRun(); cy.get(".bp3-dialog") .find("button") - .contains("Confirm") + .contains("Yes") .click(); cy.wait("@postExecute").should( "have.nested.property", @@ -37,13 +37,7 @@ describe("Confirm run action", function() { 200, ); - cy.get(queryEditor.queryMoreAction).click(); - cy.get(queryEditor.deleteUsingContext).click(); - cy.wait("@deleteAction").should( - "have.nested.property", - "response.body.responseMeta.status", - 200, - ); + cy.deleteQueryUsingContext(); cy.deleteDatasource(datasourceName); }); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/QueryPane/Mongo_Spec.js b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/QueryPane/Mongo_Spec.js index ffbb345b00..9fb7646585 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/QueryPane/Mongo_Spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/QueryPane/Mongo_Spec.js @@ -2,7 +2,6 @@ const queryLocators = require("../../../../locators/QueryEditor.json"); const generatePage = require("../../../../locators/GeneratePage.json"); const datasource = require("../../../../locators/DatasourcesEditor.json"); import homePage from "../../../../locators/HomePage"; -const explorer = require("../../../../locators/explorerlocators.json"); import { AggregateHelper } from "../../../../support/Pages/AggregateHelper"; let datasourceName; @@ -163,7 +162,7 @@ describe("Create a query with a mongo datasource, run, save and then delete the cy.deleteQueryUsingContext(); }); - it("7. Verify generation of NewPage from collection [Select]", function() { + it("7. Verify generation of NewPage from collection [Select] + Bug 12162", function() { //Verifying Select from UI cy.NavigateToDSGeneratePage(datasourceName); cy.get(generatePage.selectTableDropdown).click(); @@ -191,6 +190,20 @@ describe("Create a query with a mongo datasource, run, save and then delete the ); //This verifies the Select on the table, ie page is created fine cy.ClickGotIt(); + + //Check if table is loaded & CRUD is success + + cy.get(generatePage.selectedRow).should("exist"); + cy.get(generatePage.updateBtn) + .closest("button") + .then((selector) => { + cy.get(selector) + .invoke("attr", "class") + .then((classes) => { + cy.log("classes are:" + classes); + expect(classes).not.contain("bp3-disabled"); + }); + }); }); it("8. Validate Deletion of the Newly Created Page", () => { @@ -198,13 +211,19 @@ describe("Create a query with a mongo datasource, run, save and then delete the cy.NavigateToActiveTab(); cy.contains(".t--datasource-name", datasourceName).click(); cy.get(".t--delete-datasource").click(); - cy.get("[data-cy=t--confirm-modal-btn]").click(); + cy.get(".t--delete-datasource") + .contains("Are you sure?") + .click(); cy.wait("@deleteDatasource").should( "have.nested.property", "response.body.responseMeta.status", 409, ); - cy.actionContextMenuByEntityName("ListingAndReviews"); + cy.actionContextMenuByEntityName( + "ListingAndReviews", + "Delete", + "Are you sure?", + ); }); it("9. Bug 7399: Validate Form based & Raw command based templates", function() { @@ -281,7 +300,7 @@ describe("Create a query with a mongo datasource, run, save and then delete the ); }); cy.CheckAndUnfoldEntityItem("QUERIES/JS"); - cy.actionContextMenuByEntityName("Query1"); + cy.actionContextMenuByEntityName("Query1", "Delete", "Are you sure?"); }); it("10. Delete the datasource after NewPage deletion is success", () => { @@ -289,7 +308,9 @@ describe("Create a query with a mongo datasource, run, save and then delete the cy.NavigateToActiveTab(); cy.contains(".t--datasource-name", datasourceName).click(); cy.get(".t--delete-datasource").click(); - cy.get("[data-cy=t--confirm-modal-btn]").click(); + cy.get(".t--delete-datasource") + .contains("Are you sure?") + .click(); // cy.wait("@deleteDatasource").should( // "have.nested.property", // "response.body.responseMeta.status", diff --git a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/QueryPane/Postgres_Spec.js b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/QueryPane/Postgres_Spec.js index 861eb811bc..d00027929e 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/QueryPane/Postgres_Spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/QueryPane/Postgres_Spec.js @@ -207,15 +207,18 @@ describe("Validate CRUD queries for Postgres along with UI flow verifications", cy.xpath(generatePage.genderField).type("Male"); cy.xpath(generatePage.emailField) .type("curduser31@ihg.com") - .wait(1000); //Waiting for Submit button to get enabled + .wait(2000); //Waiting for Submit button to get enabled cy.get(generatePage.submitBtn) .closest("div") .first() .click(); cy.wait(5000); - cy.xpath(generatePage.sortByDropdown).click(); //Sorting by descending to verify newly added record - also sorting is verified + cy.get(generatePage.sortByDropdown) + .last() + .click(); //Sorting by descending to verify newly added record - also sorting is verified cy.xpath(generatePage.descending).click(); + cy.wait(2000); //for descending to take effect! cy.xpath(generatePage.currentNameField).should("have.value", "CRUD User31"); //Verifying Addition is success //Verifying Delete from UI @@ -244,14 +247,20 @@ describe("Validate CRUD queries for Postgres along with UI flow verifications", cy.NavigateToActiveTab(); cy.contains(".t--datasource-name", datasourceName).click(); cy.get(".t--delete-datasource").click(); - cy.clickButton("Confirm"); + cy.get(".t--delete-datasource") + .contains("Are you sure?") + .click(); cy.wait("@deleteDatasource").should( "have.nested.property", "response.body.responseMeta.status", 409, ); - cy.actionContextMenuByEntityName("Public.users_crud"); + cy.actionContextMenuByEntityName( + "Public.users_crud", + "Delete", + "Are you sure?", + ); }); it("10. Validate Drop of the Newly Created Table from Postgress datasource", () => { @@ -291,7 +300,9 @@ describe("Validate CRUD queries for Postgres along with UI flow verifications", cy.NavigateToActiveTab(); cy.contains(".t--datasource-name", datasourceName).click({ force: true }); cy.get(".t--delete-datasource").click({ force: true }); - cy.clickButton("Confirm"); + cy.get(".t--delete-datasource") + .contains("Are you sure?") + .click({ force: true }); // cy.wait("@deleteDatasource").should( // "have.nested.property", diff --git a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/QueryPane/S3_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/QueryPane/S3_spec.js index 4f55be5068..3690481daa 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/QueryPane/S3_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/QueryPane/S3_spec.js @@ -1,3 +1,5 @@ +/// + const queryLocators = require("../../../../locators/QueryEditor.json"); const datasource = require("../../../../locators/DatasourcesEditor.json"); const generatePage = require("../../../../locators/GeneratePage.json"); @@ -118,7 +120,7 @@ describe("Validate CRUD queries for Amazon S3 along with UI flow verifications", "File content is not base64 encoded.", ); }); - cy.validateNSelectDropdown("File Data Type", "Base64", "Text / Binary"); + cy.validateNSelectDropdown("File Data Type", "Base64", "Text"); cy.onlyQueryRun(); cy.wait("@postExecute").then(({ response }) => { @@ -247,7 +249,7 @@ describe("Validate CRUD queries for Amazon S3 along with UI flow verifications", cy.typeValueNValidate("AutoFile", "File Path"); //Commenting below since below dropdown is removed from Read - //cy.validateNSelectDropdown("File Data Type", "Base64", "Text / Binary"); + //cy.validateNSelectDropdown("File Data Type", "Base64", "Text"); cy.onlyQueryRun(); cy.wait("@postExecute").then(({ response }) => { @@ -341,7 +343,7 @@ describe("Validate CRUD queries for Amazon S3 along with UI flow verifications", ); cy.typeValueNValidate("assets-test.appsmith.com", "Bucket Name"); cy.typeValueNValidate("CRUDNewPageFile", "File Path"); - cy.validateNSelectDropdown("File Data Type", "Base64", "Text / Binary"); + cy.validateNSelectDropdown("File Data Type", "Base64", "Text"); cy.typeValueNValidate( '{"data": "Hi, this is Automation script adding file for S3 CRUD New Page validation!"}', "Content", @@ -436,17 +438,22 @@ describe("Validate CRUD queries for Amazon S3 along with UI flow verifications", cy.NavigateToActiveTab(); cy.contains(".t--datasource-name", datasourceName).click(); cy.get(".t--delete-datasource").click(); - cy.clickButton("Confirm"); + cy.get(".t--delete-datasource") + .contains("Are you sure?") + .click(); cy.wait("@deleteDatasource").should( "have.nested.property", "response.body.responseMeta.status", 409, ); - cy.actionContextMenuByEntityName("Assets-test.appsmith.com"); + cy.actionContextMenuByEntityName( + "Assets-test.appsmith.com", + "Delete", + "Are you sure?", + ); }); - //Open bug : 3836, 6492 - it.skip("7. Bug 9069, 9201, 6975, 9922, 3836, 6492: Upload/Update query is failing in S3 crud pages", function() { + it("7. Bug 9069, 9201, 6975, 9922, 3836, 6492, 11833: Upload/Update query is failing in S3 crud pages", function() { cy.NavigateToDSGeneratePage(datasourceName); cy.wait(3000); //Verifying List of Files from UI @@ -516,10 +523,10 @@ describe("Validate CRUD queries for Amazon S3 along with UI flow verifications", fixturePath + "']/ancestor::div[contains(@class, 't--widget-textwidget')]/following-sibling::div[contains(@class,'t--widget-iconbuttonwidget')]"; - cy.xpath(deleteIconButtonXPATH).should("be.visible"); - cy.xpath(deleteIconButtonXPATH) + .should("exist") .last() + .scrollIntoView() .click(); //Verifies 8684 cy.VerifyErrorMsgAbsence("Cyclic dependency found while evaluating"); //Verifies 8686 @@ -531,9 +538,13 @@ describe("Validate CRUD queries for Amazon S3 along with UI flow verifications", cy.wait("@postExecute").then(({ response }) => { expect(response.body.data.isExecutionSuccess).to.eq(true); }); - cy.get("span:contains('" + fixturePath + "')", { timeout: 10000 }).should( - "not.exist", - ); //verify Deletion of file is success from UI also + + cy.xpath( + "//div[@data-cy='overlay-comments-wrapper']//span[text()='" + + fixturePath + + "']", + { timeout: 10000 }, + ).should("not.exist"); //verify Deletion of file is success from UI also //Upload: 2 - Bug verification 9201 fixturePath = "AAAFlowerVase.jpeg"; @@ -574,30 +585,39 @@ describe("Validate CRUD queries for Amazon S3 along with UI flow verifications", "']", ).scrollIntoView(); + cy.wait(3000); //Verifying DeleteFile icon from UI cy.xpath( "//button/span[@icon='trash']/ancestor::div[contains(@class,'t--widget-iconbuttonwidget')]/preceding-sibling::div[contains(@class, 't--widget-textwidget')]//span[text()='" + fixturePath + "']/ancestor::div[contains(@class, 't--widget-textwidget')]/following-sibling::div[contains(@class,'t--widget-iconbuttonwidget')]", ) - .should("be.visible") + .should("exist") .last() + .scrollIntoView() .click(); //Verifies 8684 cy.VerifyErrorMsgAbsence("Cyclic dependency found while evaluating"); //Verifies 8686 expect( cy.xpath("//span[text()='Are you sure you want to delete the file?']"), ).to.exist; //verify Delete File dialog appears - cy.clickButton("Confirm").wait(1000); //wait for Delete operation to be successfull, //Verifies 8684 + cy.clickButton("Confirm").wait(3000); //wait for Delete operation to be successfull, //Verifies 8684 cy.wait("@postExecute").then(({ response }) => { expect(response.body.data.isExecutionSuccess).to.eq(true); }); - cy.get("span:contains('" + fixturePath + "')", { timeout: 10000 }).should( - "not.exist", - ); //verify Deletion of file is success from UI also + cy.xpath( + "//div[@data-cy='overlay-comments-wrapper']//span[text()='" + + fixturePath + + "']", + { timeout: 10000 }, + ).should("not.exist"); //verify Deletion of file is success from UI also //Deleting the page: - cy.actionContextMenuByEntityName("Assets-test.appsmith.com"); + cy.actionContextMenuByEntityName( + "Assets-test.appsmith.com", + "Delete", + "Are you sure?", + ); }); it("8. Verify 'Add to widget [Widget Suggestion]' functionality - S3", () => { @@ -660,7 +680,9 @@ describe("Validate CRUD queries for Amazon S3 along with UI flow verifications", cy.NavigateToActiveTab(); cy.contains(".t--datasource-name", datasourceName).click({ force: true }); cy.get(".t--delete-datasource").click(); - cy.clickButton("Confirm"); + cy.get(".t--delete-datasource") + .contains("Are you sure?") + .click(); // cy.wait("@deleteDatasource").should( // "have.nested.property", diff --git a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/UnitTest/LoginFromUIApp_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/UnitTest/LoginFromUIApp_spec.js index e8622e12a3..50a2dc62a2 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/UnitTest/LoginFromUIApp_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/UnitTest/LoginFromUIApp_spec.js @@ -22,6 +22,9 @@ describe("Login from UI and check the functionality", function() { cy.get(pages.deletePage) .first() .click({ force: true }); + cy.get(pages.deletePageConfirm) + .first() + .click({ force: true }); cy.wait(2000); }); cy.wait("@deletePage"); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/UserProfile/UpdateUsersName_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/UserProfile/UpdateUsersName_spec.js index 4f9e2d945f..2d15f1f9cb 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/UserProfile/UpdateUsersName_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/UserProfile/UpdateUsersName_spec.js @@ -3,14 +3,16 @@ import homePage from "../../../../locators/HomePage"; describe("Update a user's name", function() { let username; - it("Update a user's name", function() { + it("1. Update a user's name", function() { cy.get(homePage.profileMenu).click(); cy.get(".t--edit-profile").click({ force: true }); cy.generateUUID().then((uid) => { username = uid; cy.get("[data-cy=t--display-name]").clear(); - cy.get("[data-cy=t--display-name]").type(username); + cy.get("[data-cy=t--display-name]") + .click() + .type(username); // Waiting as the input onchange has a debounce // eslint-disable-next-line cypress/no-unnecessary-waiting cy.wait(2000); @@ -21,7 +23,7 @@ describe("Update a user's name", function() { }); }); - it("Validate email address and Reset pwd", function() { + it("2. Validate email address and Reset pwd", function() { cy.intercept("POST", "/api/v1/users/forgotPassword", { fixture: "resetPassword.json", }).as("resetPwd"); diff --git a/app/client/cypress/locators/DatasourcesEditor.json b/app/client/cypress/locators/DatasourcesEditor.json index b3e36b972b..359fd3988f 100644 --- a/app/client/cypress/locators/DatasourcesEditor.json +++ b/app/client/cypress/locators/DatasourcesEditor.json @@ -6,7 +6,7 @@ "username": "input[name='datasourceConfiguration.authentication.username']", "password": "input[name='datasourceConfiguration.authentication.password']", "authenticationAuthtype": "[data-cy=datasourceConfiguration\\.authentication\\.authType]", - "url": "input[name='datasourceConfiguration.url']", + "url": "input[name='url']", "MongoDB": ".t--plugin-name:contains('MongoDB')", "RESTAPI": ".t--plugin-name:contains('REST API')", "PostgreSQL": ".t--plugin-name:contains('PostgreSQL')", @@ -57,5 +57,6 @@ "mockUserDatasources":".t--datasource-name:contains('Users')", "mongoUriDropdown": "//p[text()='Use Mongo Connection String URI']/following-sibling::div", "mongoUriYes": "//div[text()='Yes']", - "mongoUriInput":"//p[text()='Connection String URI']/following-sibling::div//input" + "mongoUriInput":"//p[text()='Connection String URI']/following-sibling::div//input", + "saveBtn": ".t--save-datasource" } diff --git a/app/client/cypress/locators/FormWidgets.json b/app/client/cypress/locators/FormWidgets.json index 52d83df5ef..8b3c240b0e 100644 --- a/app/client/cypress/locators/FormWidgets.json +++ b/app/client/cypress/locators/FormWidgets.json @@ -43,7 +43,7 @@ "radioInput": ".t--draggable-radiogroupwidget span.t--widget-name", "checkboxGroupInput": ".t--draggable-checkboxgroupwidget span.t--widget-name", "switchGroupInput": ".t--draggable-switchgroupwidget span.t--widget-name", - "radioAddButton": ".t--property-control-options button", + "radioAddButton": ".t--property-control-options button.t--property-control-options-add", "formD": "div[type='FORM_WIDGET']", "datepickerFooter": ".bp3-datepicker-footer span", "datepickerFooterPublish": ".bp3-datepicker-footer span", @@ -67,4 +67,4 @@ "apiCallToast": "div.t--toast-action span[type='p1']", "toggleOnOptionChange": ".t--property-control-onoptionchange .t--js-toggle", "toggleButtonVariant": ".t--property-control-buttonvariant .t--js-toggle" -} \ No newline at end of file +} diff --git a/app/client/cypress/locators/GeneratePage.json b/app/client/cypress/locators/GeneratePage.json index 92a7d62ec1..141e6441c2 100644 --- a/app/client/cypress/locators/GeneratePage.json +++ b/app/client/cypress/locators/GeneratePage.json @@ -17,7 +17,7 @@ "genderField": "//input[@placeholder='gender']", "emailField": "//input[@placeholder='email']", "submitBtn": "span:contains('Submit')", - "sortByDropdown": "//div[@type='CANVAS_WIDGET']/div[contains(@class, 't--widget-dropdownwidget')][2]", + "sortByDropdown": "span[name='dropdown']", "ascending": "//div[text()='Ascending']", "descending": "//div[text()='Descending']", "currentNameField": "//div[@type='FORM_WIDGET']//span[text()='name:']//ancestor::div[contains(@class,'t--widget-textwidget')]/following-sibling::div[contains(@class, 't--widget-inputwidgetv2')][1]//input", @@ -25,5 +25,6 @@ "confirmBtn": "span:contains('Confirm')", "deleteMenuItem": "//div[text()='Delete']/parent::a[contains(@class, 'single-select')]", "uploadFilesS3":"div.uppy-Dashboard-AddFiles input", - "uploadBtn": "button.uppy-StatusBar-actionBtn--upload" + "uploadBtn": "button.uppy-StatusBar-actionBtn--upload", + "selectedRow": ".tr.selected-row" } \ No newline at end of file diff --git a/app/client/cypress/locators/HomePage.js b/app/client/cypress/locators/HomePage.js index 003ebc9871..a037d7a086 100644 --- a/app/client/cypress/locators/HomePage.js +++ b/app/client/cypress/locators/HomePage.js @@ -58,6 +58,7 @@ export default { enablePublicAccess: ".t--share-public-toggle .slider", closeBtn: ".bp3-dialog-close-button", applicationName: ".t--application-name", + applicationEditMenu: ".t--application-edit-menu", editingAppName: "bp3-editable-text-editing", portalMenuItem: ".bp3-portal .bp3-menu-item", profileMenu: ".bp3-popover-wrapper.profile-menu", @@ -93,4 +94,5 @@ export default { orgCompleteSection: ".t--org-section", orgNameText: ".t--org-name-text", optionsIcon: ".t--options-icon", + reconnectDatasourceModal: ".reconnect-datasource-modal", }; diff --git a/app/client/cypress/locators/JSEditor.json b/app/client/cypress/locators/JSEditor.json index 0a367dbec9..c89e9aa26a 100644 --- a/app/client/cypress/locators/JSEditor.json +++ b/app/client/cypress/locators/JSEditor.json @@ -7,6 +7,7 @@ "jsPageProperty": ".entity-context-menu", "propertyList": ".t--entity-property", "delete": ".single-select >div:contains('Delete')", + "deleteConfirm": ".single-select >div:contains('Are you sure?')", "popover": "//*[local-name()='g' and @id='Icon/Outline/more-vertical']" } diff --git a/app/client/cypress/locators/Omnibar.json b/app/client/cypress/locators/Omnibar.json new file mode 100644 index 0000000000..d180ec8ec1 --- /dev/null +++ b/app/client/cypress/locators/Omnibar.json @@ -0,0 +1,10 @@ +{ + "globalSearch": ".t--global-search-modal-trigger", + "globalSearchInput": ".t--global-search-input", + "discordLink":".discord", + "categoryTitle":".category-title", + "openDocumentationLink":".documentation-cta", + "globalSearchClose":".t--global-clear-input", + "createNew":".t--file-operation", + "recentlyopenItem":"//span[@class='text']" +} \ No newline at end of file diff --git a/app/client/cypress/locators/Pages.json b/app/client/cypress/locators/Pages.json index b68297e32d..8424df062a 100644 --- a/app/client/cypress/locators/Pages.json +++ b/app/client/cypress/locators/Pages.json @@ -20,6 +20,7 @@ "editName": ".single-select >div:contains('Edit Name')", "clonePage": ".single-select >div:contains('Clone')", "deletePage": ".single-select >div:contains('Delete')", + "deletePageConfirm": ".single-select >div:contains('Are you sure?')", "hidePage": ".single-select >div:contains('Hide')", "entityQuery": ".t--entity-name:contains('Queries')", "showPage": ".single-select >div:contains('Show')" diff --git a/app/client/cypress/locators/ReconnectLocators.js b/app/client/cypress/locators/ReconnectLocators.js new file mode 100644 index 0000000000..71e9d06619 --- /dev/null +++ b/app/client/cypress/locators/ReconnectLocators.js @@ -0,0 +1,5 @@ +export default { + Modal: ".reconnect-datasource-modal", + ClostBtn: ".t--reconnect-close-btn", + SkipToAppBtn: ".t--skip-to-application-btn", +}; diff --git a/app/client/cypress/locators/Widgets.json b/app/client/cypress/locators/Widgets.json index 9b2fdd75bd..0af8975f02 100644 --- a/app/client/cypress/locators/Widgets.json +++ b/app/client/cypress/locators/Widgets.json @@ -20,6 +20,7 @@ "selectwidget": ".t--widget-selectwidget", "textWidget": ".t--draggable-textwidget", "tableWidget": ".t--draggable-tablewidget", + "jsonFormWidget": ".t--draggable-jsonformwidget", "tableOnRowSelected": ".t--property-control-onrowselected", "dropdownSelectButton": ".t--open-dropdown-Select", "buttonOnClick": ".t--property-control-onclick .bp3-popover-target", @@ -69,7 +70,7 @@ "defaultSingleSelectValue": ".bp3-popover-target > div > .bp3-button > .bp3-button-text", "widgetBtn": ".t--widget-buttonwidget button", "widgetBtnText": ".t--widget-buttonwidget button .bp3-button-text", - "iconWidgetBtn": ".t--widget-iconwidget svg", + "iconWidgetBtn": ".t--draggable-iconbuttonwidget button", "actionSelect": ".t--open-dropdown-Select-Action", "inputOnTextChange": ".t--property-control-ontextchanged .t--open-dropdown-Select-Action", "tableActionSelect": ".t--property-control-onsearchtextchanged .t--open-dropdown-Select-Action", diff --git a/app/client/cypress/locators/apiWidgetslocator.json b/app/client/cypress/locators/apiWidgetslocator.json index cae9a59f52..aeea1a7a79 100644 --- a/app/client/cypress/locators/apiWidgetslocator.json +++ b/app/client/cypress/locators/apiWidgetslocator.json @@ -10,6 +10,7 @@ "copyTo": ".single-select >div:contains('Copy to page')", "home": ".single-select >div:contains('Page1')", "delete": ".single-select >div:contains('Delete')", + "deleteConfirm": ".single-select >div:contains('Are you sure?')", "path": ".t--path >div textarea", "editResourceUrl": ".t--dataSourceField", "autoSuggest": "//div[contains(@id,'react-select')]", diff --git a/app/client/cypress/locators/commonlocators.json b/app/client/cypress/locators/commonlocators.json index 8ef19bfbd0..98b35bcf6b 100644 --- a/app/client/cypress/locators/commonlocators.json +++ b/app/client/cypress/locators/commonlocators.json @@ -115,6 +115,8 @@ "filePickerOnFilesSelected": ".t--property-control-onfilesselected", "dataType": ".t--property-control-datatype .bp3-popover-target", "recaptchaVersion": ".t--property-control-googlerecaptchaversion .bp3-popover-target", + "jsonFormFieldType": ".t--property-control-fieldtype .bp3-popover-target", + "jsonFormAddNewCustomFieldBtn": ".t--property-control-fieldconfiguration .t--add-column-btn", "evaluateMsg": ".t--evaluatedPopup-error", "globalSearchModal": ".t--global-search-modal", "globalSearchInput": ".t--global-search-input", @@ -148,7 +150,9 @@ "errorTab": "[data-cy=t--tab-ERROR]", "debugErrorMsg": ".t--debugger-message", "debuggerLabel": "span.debugger-label", + "debuggerContextMenu":".t--debugger-contextual-error-menu", "cyclicDependencyError": "//div[@class='Toastify']//span[contains(text(),'Cyclic dependency found while evaluating')]", + "openDocumentationfromErrorTab":"//span[@name='book-line']", "appNameDeployMenu": ".t--app-name-menu-deploy-parent", "appNameDeployMenuPublish": ".t--app-name-menu-deploy", "appNameDeployMenuCurrentVersion": ".t--app-name-menu-deploy-current-version", @@ -161,4 +165,4 @@ "dashboardItemName": ".uppy-Dashboard-Item-name", "mapChartShowLabels": ".t--property-control-showlabels input", "widgetSection": ".t--entity.widgets > .t--entity-item > a.t--entity-collapse-toggle" -} \ No newline at end of file +} diff --git a/app/client/cypress/locators/publishWidgetspage.json b/app/client/cypress/locators/publishWidgetspage.json index efc8b31526..09667f6659 100644 --- a/app/client/cypress/locators/publishWidgetspage.json +++ b/app/client/cypress/locators/publishWidgetspage.json @@ -1,5 +1,6 @@ { "buttonWidget": ".t--widget-buttonwidget", + "iconWidgetBtn": ".t--widget-iconbuttonwidget button", "textWidget": ".t--widget-textwidget", "richTextEditorWidget": ".t--widget-richtexteditorwidget", "datepickerWidget": ".t--widget-datepickerwidget", @@ -18,6 +19,7 @@ "multiselecttreewidget": ".t--widget-multiselecttreewidget", "singleselecttreewidget": ".t--widget-singleselecttreewidget", "tabWidget": ".t--widget-tabswidget", + "jsonFormWidget": ".t--widget-jsonformwidget", "chartWidget": ".t--widget-chartwidget", "horizontalTab": ".t--widget-chartwidget g[class*='-scrollContainer'] rect", "tableWidget": ".t--widget-tablewidget", diff --git a/app/client/cypress/manual_TestSuite/CommentedScriptFiles/AForceMigration_Spec.ts b/app/client/cypress/manual_TestSuite/CommentedScriptFiles/AForceMigration_Spec.ts new file mode 100644 index 0000000000..4e412fc32f --- /dev/null +++ b/app/client/cypress/manual_TestSuite/CommentedScriptFiles/AForceMigration_Spec.ts @@ -0,0 +1,507 @@ +// const widgetsPage = require("../../../locators/Widgets.json"); +// import homePage from "../../locators/HomePage"; + +// describe("Migration Validate", function () { +// it("1. Import application and Validate Migration on pageload", function () { +// // import application +// cy.get(homePage.homeIcon).click(); +// cy.get(homePage.optionsIcon) +// .first() +// .click(); +// cy.get(homePage.orgImportAppOption).click({ force: true }); +// cy.get(homePage.orgImportAppModal).should("be.visible"); +// cy.xpath(homePage.uploadLogo) +// .attachFile("TableMigrationAppExported.json") +// .wait(500); +// cy.get(homePage.orgImportAppButton) +// .trigger("click") +// .wait(500); +// cy.get(homePage.orgImportAppModal).should("not.exist"); + +// cy.wait("@importNewApplication").then((interception) => { +// let appId = interception.response.body.data.id; +// let defaultPage = interception.response.body.data.pages.find( +// (eachPage) => !!eachPage.isDefault, +// ); + +// cy.get(homePage.toastMessage).should( +// "contain", +// "Application imported successfully", +// ); + +// //Renaming imported app! +// const uuid = () => Cypress._.random(0, 1e4); +// const name = uuid(); +// cy.wait(2000); +// cy.get(homePage.applicationName) +// .clear() +// .type(`app${name}`); +// cy.wrap(`app${name}`).as("appname"); +// cy.wait(2000); + +// // Validating data binding for the imported application - Page1 + +// //Validating Latitude & Longitude are hidden columns: +// cy.xpath( +// "//div[@class='tableWrap']//div[@class='thead']//div[@class='tr'][1]//div[@role='columnheader']//div[text()='latitude']/parent::div/parent::div", +// ) +// .invoke("attr", "class") +// .then((classes) => { +// cy.log("classes are:" + classes); +// expect(classes).includes("hidden-header"); +// }); + +// cy.xpath( +// "//div[@class='tableWrap']//div[@class='thead']//div[@class='tr'][1]//div[@role='columnheader']//div[text()='longitude']/parent::div/parent::div", +// ) +// .invoke("attr", "class") +// .then((classes) => { +// cy.log("classes are:" + classes); +// expect(classes).includes("hidden-header"); +// }); + +// //Validating order of header row! +// cy.xpath( +// "//div[@class='tableWrap']//div[@class='thead']//div[@class='tr'][1]", +// ) +// .invoke("text") +// .then((x) => { +// expect(x).to.eq( +// "Card NumberidNameاسمaddress住所PhoneemailCompanyjobimagessnPin CodeCreditLimitOutstandingStateAvailable LimitCard TypeChange Credit limitimageURLlatitudelongitude", +// ); +// cy.log("header set is:" + x); +// }); + +// //Validating Id column sorting happens as Datatype is Number in app! +// cy.xpath( +// "//div[@class='tableWrap']//div[@class='thead']//div[@class='tr'][1]//div[@role='columnheader']//div[text()='id']", +// ) +// .click() +// .wait(2000); + +// cy.readTabledataPublish("0", "1").then((cellData) => { +// expect(cellData).to.be.equal("100"); +// }); + +// cy.readTabledataPublish("1", "1").then((cellData) => { +// expect(cellData).to.be.equal("99"); +// }); + +// cy.readTabledataPublish("2", "1").then((cellData) => { +// expect(cellData).to.be.equal("98"); +// }); + +// //Revert the Id column sorting! +// cy.xpath( +// "//div[@class='tableWrap']//div[@class='thead']//div[@class='tr'][1]//div[@role='columnheader']//div[text()='id']", +// ) +// .click() +// .wait(2000); + +// cy.readTabledataPublish("0", "1").then((cellData) => { +// expect(cellData).to.be.equal("1"); +// }); + +// cy.readTabledataPublish("1", "1").then((cellData) => { +// expect(cellData).to.be.equal("2"); +// }); + +// cy.readTabledataPublish("2", "1").then((cellData) => { +// expect(cellData).to.be.equal("3"); +// }); + +// //Validating image column is present: +// cy.getTableDataSelector("0", "10").then((selector) => { +// cy.get(selector + " div") +// .invoke("attr", "class") +// .then((classes) => { +// cy.log("classes are:" + classes); +// expect(classes).to.eq("image-cell"); +// }); +// }); + +// //Card Number mapping to text widget! +// cy.isSelectRow(2); +// cy.wait(2500); //time for table row select to reflect! +// cy.readTabledataPublish("2", "0").then((cardNumber) => { +// cy.xpath("//div[contains(@class, ' t--widget-textwidget')][1]") +// .eq(1) +// .invoke("text") +// .then((cardNo) => { +// var format = /^\d{4}-\d{4}-\d{4}(-\d{4})?$/; +// expect(cardNumber).match(format); +// expect(cardNumber).to.be.equal(cardNo); +// }); +// }); + +// //Address mapping to text widget! +// cy.readTabledataPublish("2", "4").then((address) => { +// cy.xpath("//div[contains(@class, ' t--widget-textwidget')][2]") +// .eq(1) +// .invoke("text") +// .then((addr) => { +// expect(address.replace(/\r?\n|\r/, "")).to.eq(addr); +// }); +// }); + +// //Validating Available limit column computation maintained! +// cy.readTabledataPublish("2", "16").then((availLimit) => { +// cy.readTabledataPublish("2", "13").then((creditLimit) => { +// cy.readTabledataPublish("2", "14").then((outstanding) => { +// expect(Number(availLimit)).to.eq(creditLimit - outstanding); +// }); +// }); +// }); + +// //Validating State button click & binding & text widget mapping! +// cy.getTableDataSelector("2", "15").then((selector) => { +// cy.get(selector + " button.bp3-button") +// .click() +// .wait(3000); + +// cy.waitUntil( +// () => +// cy +// .xpath("//div[contains(@class, ' t--widget-textwidget')][2]", { +// timeout: 30000, +// }) +// .eq(0) +// .should("contain.text", "State:"), +// { +// errorMsg: "Execute call did not complete evn after 10 secs", +// timeout: 20000, +// interval: 1000, +// }, +// ).then(() => cy.wait(500)); + +// cy.get(selector + " button span") +// .invoke("text") +// .then((statetxt) => { +// cy.xpath("//div[contains(@class, ' t--widget-textwidget')][2]") +// .eq(0) +// .invoke("text") +// .then((txtWidtxt) => { +// cy.log("statetxt is:" + statetxt); +// let text = +// statetxt == "Activate" ? "State:Inactive" : "State:Active"; +// expect(text).to.eq(txtWidtxt); +// }); +// }); +// }); + +// //Validating Image URL click & navigation! +// cy.getTableDataSelector("2", "19").then((selector) => { +// // Stubbing window.open to open in the same tab +// cy.window().then((window) => { +// cy.stub(window, "open").callsFake((url) => { +// window.location.href = url; //.substring(1); +// window.location.target = "_self"; +// }); +// }); + +// cy.get(selector + " span.bp3-popover-target span") +// .invoke("text") +// .then((url) => { +// cy.get(selector + " span.bp3-popover-target") +// .click() +// .wait(2000); +// cy.wait("@postExecute"); +// cy.url().should("contain", url); +// cy.go(-1); +// }); +// }); + +// // cy.wait(4000); +// // cy.get("div.tableWrap").should("be.visible"); //wait for page load! + +// cy.waitUntil( +// () => cy.get("div.tableWrap", { timeout: 30000 }).should("be.visible"), +// { +// errorMsg: "Page is not loaded evn after 10 secs", +// timeout: 30000, +// interval: 2000, +// }, +// ).then(() => cy.wait(1000)); //wait for page load! + +// cy.isSelectRow(2); //as aft refresh row selection is also gone +// cy.getTableDataSelector("2", "18").then((selector) => { +// cy.get(selector + " button") +// .click() +// .wait(1000); + +// cy.xpath( +// "//div//a[contains(@class, 'bp3-menu-item')]/div[text()='AddcreditLimit']/parent::a", +// ) +// .click() +// .wait(2000); + +// cy.waitUntil( +// () => +// cy +// .xpath("//div[contains(@class, ' t--widget-textwidget')][1]", { +// timeout: 30000, +// }) +// .eq(0) +// .should("contain.text", "CreditLimit:"), +// { +// errorMsg: "Execute call did not complete evn after 10 secs", +// timeout: 20000, +// interval: 1000, +// }, +// ).then(() => cy.wait(500)); //allow time for n/w to finish + +// cy.xpath("//div[contains(@class, ' t--widget-textwidget')][1]", { +// timeout: 30000, +// }) +// .eq(0) +// .invoke("text") +// .then((addreduce) => { +// expect(addreduce).to.eq("CreditLimit:Add"); +// }); +// }); + +// //Manu Btn validation: - 2nd menu item +// cy.getTableDataSelector("2", "18").then((selector) => { +// cy.get(selector + " button") +// .click() +// .wait(1000); + +// cy.xpath( +// "//div//a[contains(@class, 'bp3-menu-item')]/div[text()='Reducecreditlimit']/parent::a", +// ) +// .click() +// .wait(2000); + +// cy.waitUntil( +// () => +// cy +// .xpath("//div[contains(@class, ' t--widget-textwidget')][1]", { +// timeout: 30000, +// }) +// .eq(0) +// .should("contain.text", "CreditLimit:"), +// { +// errorMsg: "Execute call did not complete evn after 10 secs", +// timeout: 20000, +// interval: 1000, +// }, +// ).then(() => cy.wait(500)); //allow time for n/w to finish + +// cy.xpath("//div[contains(@class, ' t--widget-textwidget')][1]", { +// timeout: 30000, +// }) +// .eq(0) +// .invoke("text") +// .then((addreduce) => { +// expect(addreduce).to.eq("CreditLimit:Reduce"); +// }); +// }); + +// //Another row! +// //Card Number mapping to text widget! +// cy.isSelectRow(4); +// cy.wait(2500); //time for table row select to reflect! +// cy.readTabledataPublish("4", "0").then((cardNumber) => { +// cy.xpath("//div[contains(@class, ' t--widget-textwidget')][1]") +// .eq(1) +// .invoke("text") +// .then((cardNo) => { +// var format = /^\d{4}-\d{4}-\d{4}(-\d{4})?$/; +// expect(cardNumber).match(format); +// expect(cardNumber).to.be.equal(cardNo); +// }); +// }); + +// //Address mapping to text widget! +// cy.readTabledataPublish("4", "4").then((address) => { +// cy.xpath("//div[contains(@class, ' t--widget-textwidget')][2]") +// .eq(1) +// .invoke("text") +// .then((addr) => { +// expect(address.replace(/\r?\n|\r/, "")).to.eq(addr); +// }); +// }); + +// //Validating Available limit column computation maintained! +// cy.readTabledataPublish("4", "16").then((availLimit) => { +// cy.readTabledataPublish("4", "13").then((creditLimit) => { +// cy.readTabledataPublish("4", "14").then((outstanding) => { +// expect(Number(availLimit)).to.eq(creditLimit - outstanding); +// }); +// }); +// }); + +// //Validating State button click & binding & text widget mapping! +// cy.getTableDataSelector("4", "15").then((selector) => { +// cy.get(selector + " button.bp3-button") +// .click() +// .wait(2000); + +// cy.waitUntil( +// () => +// cy +// .xpath("//div[contains(@class, ' t--widget-textwidget')][2]", { +// timeout: 30000, +// }) +// .eq(0) +// .should("contain.text", "State:"), +// { +// errorMsg: "Execute call did not complete evn after 10 secs", +// timeout: 20000, +// interval: 1000, +// }, +// ).then(() => cy.wait(500)); + +// cy.get(selector + " button span") +// .invoke("text") +// .then((statetxt) => { +// cy.xpath("//div[contains(@class, ' t--widget-textwidget')][2]") +// .eq(0) +// .invoke("text") +// .then((txtWidtxt) => { +// cy.log("statetxt is:" + statetxt); +// let text = +// statetxt == "Activate" ? "State:Inactive" : "State:Active"; +// expect(text).to.eq(txtWidtxt); +// }); +// }); +// }); + +// //Validating Image URL click & navigation! +// cy.getTableDataSelector("4", "19").then((selector) => { +// // Stubbing window.open to open in the same tab +// cy.window().then((window) => { +// cy.stub(window, "open").callsFake((url) => { +// window.location.href = url; //.substring(1); +// window.location.target = "_self"; +// }); +// }); + +// cy.get(selector + " span.bp3-popover-target span") +// .invoke("text") +// .then((url) => { +// cy.get(selector + " span.bp3-popover-target") +// .click() +// .wait(2000); +// cy.wait("@postExecute"); +// cy.url().should("contain", url); +// cy.go(-1); +// }); +// }); + +// //cy.wait(4000); +// //cy.get("div.tableWrap").should("be.visible"); + +// cy.waitUntil( +// () => cy.get("div.tableWrap", { timeout: 30000 }).should("be.visible"), +// { +// errorMsg: "Page is not loaded evn after 10 secs", +// timeout: 30000, +// interval: 2000, +// }, +// ).then(() => cy.wait(1000)); //wait for page load! + +// //Manu Btn validation: - 1st menu item +// cy.isSelectRow(4); //as aft refresh row selection is also gone +// cy.getTableDataSelector("4", "18").then((selector) => { +// cy.get(selector + " button") +// .click() +// .wait(1000); + +// cy.xpath( +// "//div//a[contains(@class, 'bp3-menu-item')]/div[text()='AddcreditLimit']/parent::a", +// ) +// .click() +// .wait(2000); //allow time for n/w to finish + +// cy.waitUntil( +// () => +// cy +// .xpath("//div[contains(@class, ' t--widget-textwidget')][1]", { +// timeout: 30000, +// }) +// .eq(0) +// .should("contain.text", "CreditLimit:"), +// { +// errorMsg: "Execute call did not complete evn after 10 secs", +// timeout: 20000, +// interval: 1000, +// }, +// ).then(() => cy.wait(500)); //allow time for n/w to finish + +// cy.xpath("//div[contains(@class, ' t--widget-textwidget')][1]", { +// timeout: 30000, +// }) +// .eq(0) +// .invoke("text") +// .then((addreduce) => { +// expect(addreduce).to.eq("CreditLimit:Add"); +// }); +// }); + +// //Manu Btn validation: - 2nd menu item +// cy.getTableDataSelector("4", "18").then((selector) => { +// cy.get(selector + " button") +// .click() +// .wait(1000); + +// cy.xpath( +// "//div//a[contains(@class, 'bp3-menu-item')]/div[text()='Reducecreditlimit']/parent::a", +// ) +// .click() +// .wait(2000); //allow time for n/w to finish + +// cy.waitUntil( +// () => +// cy +// .xpath("//div[contains(@class, ' t--widget-textwidget')][1]", { +// timeout: 30000, +// }) +// .eq(0) +// .should("contain.text", "CreditLimit:"), +// { +// errorMsg: "Execute call did not complete evn after 10 secs", +// timeout: 20000, +// interval: 1000, +// }, +// ).then(() => cy.wait(500)); //allow time for n/w to finish + +// cy.xpath("//div[contains(@class, ' t--widget-textwidget')][1]", { +// timeout: 30000, +// }) +// .eq(0) +// .invoke("text") +// .then((addreduce) => { +// expect(addreduce).to.eq("CreditLimit:Reduce"); +// }); +// }); +// }); + +// //Page 2 Validations: + +// cy.selectEntityByName("Change color and font"); +// cy.selectEntityByName("WIDGETS"); +// cy.selectEntityByName("Table1"); + +// cy.get(widgetsPage.bold) +// .invoke("attr", "aria-selected") +// .then((sel) => expect(Boolean(sel)).to.be.true); +// cy.get(widgetsPage.centerAlign) +// .eq(0) +// .invoke("attr", "aria-selected") +// .then((sel) => expect(Boolean(sel)).to.be.true); //Text align +// cy.get(widgetsPage.centerAlign) +// .eq(1) +// .invoke("attr", "aria-selected") +// .then((sel) => expect(Boolean(sel)).to.be.true); //Vertical align +// cy.get(widgetsPage.textColor) +// .first() +// .invoke("attr", "value") +// .should("contain", "#2E3D49"); +// cy.get(`${widgetsPage.cellBackground} input`) +// .first() +// .invoke("attr", "value") +// .should("contain", "#FFC13D"); +// cy.get(widgetsPage.selectedTextSize).should("have.text", "24px"); +// }); +// }); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/Datasources/DatasourceBasicProfile_spec.js b/app/client/cypress/manual_TestSuite/CommentedScriptFiles/DatasourceBasicProfile_spec.js similarity index 100% rename from app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/Datasources/DatasourceBasicProfile_spec.js rename to app/client/cypress/manual_TestSuite/CommentedScriptFiles/DatasourceBasicProfile_spec.js diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/FormWidgets/Dropdown_spec.js b/app/client/cypress/manual_TestSuite/CommentedScriptFiles/Dropdown_spec.js similarity index 100% rename from app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/FormWidgets/Dropdown_spec.js rename to app/client/cypress/manual_TestSuite/CommentedScriptFiles/Dropdown_spec.js diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/Map_spec.js b/app/client/cypress/manual_TestSuite/CommentedScriptFiles/Map_spec.js similarity index 94% rename from app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/Map_spec.js rename to app/client/cypress/manual_TestSuite/CommentedScriptFiles/Map_spec.js index cf73f6dfb0..119239e6bd 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/Map_spec.js +++ b/app/client/cypress/manual_TestSuite/CommentedScriptFiles/Map_spec.js @@ -1,7 +1,7 @@ -const commonlocators = require("../../../../locators/commonlocators.json"); -const viewWidgetsPage = require("../../../../locators/ViewWidgets.json"); -const dsl = require("../../../../fixtures/Mapdsl.json"); -const publishPage = require("../../../../locators/publishWidgetspage.json"); +const commonlocators = require("../../locators/commonlocators.json"); +const viewWidgetsPage = require("../../locators/ViewWidgets.json"); +const dsl = require("../../fixtures/Mapdsl.json"); +const publishPage = require("../../locators/publishWidgetspage.json"); if (Cypress.env("APPSMITH_GOOGLE_MAPS_API_KEY")) { describe("Map Widget Functionality", function() { diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/GenerateCRUD/MsSQL_Spec.js b/app/client/cypress/manual_TestSuite/CommentedScriptFiles/MsSQL_Spec.js similarity index 100% rename from app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/GenerateCRUD/MsSQL_Spec.js rename to app/client/cypress/manual_TestSuite/CommentedScriptFiles/MsSQL_Spec.js diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/Table_Duplicate_ColumnName_spec.js b/app/client/cypress/manual_TestSuite/CommentedScriptFiles/Table_Duplicate_ColumnName_spec.js similarity index 84% rename from app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/Table_Duplicate_ColumnName_spec.js rename to app/client/cypress/manual_TestSuite/CommentedScriptFiles/Table_Duplicate_ColumnName_spec.js index 1fbdb1ac60..164700dfc5 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/Table_Duplicate_ColumnName_spec.js +++ b/app/client/cypress/manual_TestSuite/CommentedScriptFiles/Table_Duplicate_ColumnName_spec.js @@ -1,6 +1,6 @@ -const widgetsPage = require("../../../../locators/Widgets.json"); -const dsl = require("../../../../fixtures/tableNewDsl.json"); -const commonlocators = require("../../../../locators/commonlocators.json"); +const widgetsPage = require("../../locators/Widgets.json"); +const dsl = require("../../fixtures/tableNewDsl.json"); +const commonlocators = require("../../locators/commonlocators.json"); describe("prevent duplicate column name in table", function() { before(() => { diff --git a/app/client/cypress/support/Objects/CommonLocators.ts b/app/client/cypress/support/Objects/CommonLocators.ts index c3c280a283..a4e6514f6e 100644 --- a/app/client/cypress/support/Objects/CommonLocators.ts +++ b/app/client/cypress/support/Objects/CommonLocators.ts @@ -13,7 +13,7 @@ export class CommonLocators { _codeMirrorTextArea = ".CodeMirror textarea" _codeMirrorCode = ".CodeMirror-code" _codeEditorTargetTextArea = ".CodeEditorTarget textarea" - _codeEditorTarget = "//div[@class='CodeEditorTarget']" + _codeEditorTarget = "div.CodeEditorTarget" _entityExplorersearch = "#entity-explorer-search" _propertyControl = ".t--property-control-" _textWidget = ".t--draggable-textwidget span" @@ -32,12 +32,12 @@ export class CommonLocators { _entityNameInExplorer = (entityNameinLeftSidebar: string) => "//div[contains(@class, 't--entity-name')][text()='" + entityNameinLeftSidebar + "']" _expandCollapseArrow = (entityNameinLeftSidebar: string) => "//div[text()='" + entityNameinLeftSidebar + "']/ancestor::div/preceding-sibling::a[contains(@class, 't--entity-collapse-toggle')]" _entityProperties = (entityNameinLeftSidebar: string) => "//div[text()='" + entityNameinLeftSidebar + "']/ancestor::div[contains(@class, 't--entity-item')]/following-sibling::div//div[contains(@class, 't--entity-property')]//code" - _contextMenu = (entityNameinLeftSidebar: string) => "//div[text()='" + entityNameinLeftSidebar + "']/ancestor::div[contains(@class, 't--entity')]//span[contains(@class, 'entity-context-menu')]//div" - _contextMenuItem = (item: string) => "//div[text()='" + item + "']/parent::a[contains(@class, 'single-select')]" + _contextMenu = (entityNameinLeftSidebar: string) => "//div[text()='" + entityNameinLeftSidebar + "']/ancestor::div[1]/following-sibling::div//div[contains(@class, 'entity-context-menu-icon')]" + _contextMenuItem = (item: string) => "//div[text()='" + item + "']/ancestor::a[contains(@class, 'single-select')]" _entityNameEditing = (entityNameinLeftSidebar: string) => "//span[text()='" + entityNameinLeftSidebar + "']/parent::div[contains(@class, 't--entity-name editing')]/input" _jsToggle = (controlToToggle: string) => ".t--property-control-" + controlToToggle + " .t--js-toggle" _spanButton = (btnVisibleText: string) => "//span[text()='" + btnVisibleText + "']/parent::button" - _selectPropDropdown = (ddName: string) => "//div[contains(@class, 't--property-control-" + ddName + "')]//button" + _selectPropDropdown = (ddName: string) => "//div[contains(@class, 't--property-control-" + ddName + "')]//button[contains(@class, 't--open-dropdown-Select-Action')]" _dropDownValue = (ddOption: string) => ".single-select:contains('" + ddOption + "')" _actionTextArea = (actionName: string) => "//label[text()='" + actionName + "']/following-sibling::div//div[contains(@class, 'CodeMirror')]//textarea" _existingDefaultTextInput = ".t--property-control-defaulttext .CodeMirror-code" diff --git a/app/client/cypress/support/Pages/AggregateHelper.ts b/app/client/cypress/support/Pages/AggregateHelper.ts index bdfbe62bc1..d35f596a63 100644 --- a/app/client/cypress/support/Pages/AggregateHelper.ts +++ b/app/client/cypress/support/Pages/AggregateHelper.ts @@ -10,10 +10,7 @@ export class AggregateHelper { let pageid: string; let layoutId; cy.url().then((url) => { - currentURL = url; - const myRegexp = /pages(.*)/; - const match = myRegexp.exec(currentURL); - pageid = match![1].split("/")[1]; + pageid = url.split("/")[4]?.split("-").pop() as string; cy.log(pageid + "page id"); //Fetch the layout id cy.request("GET", "api/v1/pages/" + pageid).then((response) => { @@ -23,15 +20,15 @@ export class AggregateHelper { cy.request( "PUT", "api/v1/layouts/" + layoutId + "/pages/" + pageid, - dsl, - ).then((response) => { - //cy.log("Pages resposne is : " + response.body); - expect(response.status).equal(200); + dsl + ).then((dslDumpResp) => { + //cy.log("Pages resposne is : " + dslDumpResp.body); + expect(dslDumpResp.status).equal(200); cy.reload(); }); }); }); - this.Sleep(2000)//settling time for dsl + this.Sleep(5000)//settling time for dsl } public NavigateToDSCreateNew() { @@ -106,18 +103,17 @@ export class AggregateHelper { }); cy.get(locator._publishButton).click(); cy.wait("@publishApp"); - cy.url().should("include", "/pages"); cy.log("Pagename: " + localStorage.getItem("PageName")); } public expandCollapseEntity(entityName: string, expand = true) { cy.xpath(locator._expandCollapseArrow(entityName)).invoke('attr', 'name').then((arrow) => { if (expand && arrow == 'arrow-right') - cy.xpath(locator._expandCollapseArrow(entityName)).click({ multiple: true }).wait(500); + cy.xpath(locator._expandCollapseArrow(entityName)).trigger('click', { multiple: true }).wait(1000); else if (!expand && arrow == 'arrow-down') - cy.xpath(locator._expandCollapseArrow(entityName)).click({ multiple: true }).wait(500); + cy.xpath(locator._expandCollapseArrow(entityName)).trigger('click', { multiple: true }).wait(1000); else - cy.wait(500) + this.Sleep() }) } @@ -216,7 +212,7 @@ export class AggregateHelper { .first() .focus() .type("{uparrow}", { force: true }) - .type("{ctrl}{shift}{downarrow}", { force: true }); + .type("{ctrl}{shift}{downarrow}{del}", { force: true }); cy.focused().then(($cm: any) => { if ($cm.contents != "") { cy.log("The field is not empty"); @@ -329,15 +325,16 @@ export class AggregateHelper { subAction = "") { this.Sleep(); cy.xpath(locator._contextMenu(entityNameinLeftSidebar)) - .first() + .last() .click({ force: true }); cy.xpath(locator._contextMenuItem(action)) .click({ force: true }) - .wait(500); - if (subAction) + this.Sleep(500) + if (subAction) { cy.xpath(locator._contextMenuItem(subAction)) .click({ force: true }) - .wait(500); + this.Sleep(500) + } } public ValidateEntityAbsenceInExplorer(entityNameinLeftSidebar: string) { @@ -355,7 +352,7 @@ export class AggregateHelper { this.UpdateCodeInput($field, valueToType); }); } else { - cy.xpath(locator._codeEditorTarget).then(($field: any) => { + cy.get(locator._codeEditorTarget).then(($field: any) => { this.UpdateCodeInput($field, valueToType); }); } diff --git a/app/client/cypress/support/Pages/HomePage.ts b/app/client/cypress/support/Pages/HomePage.ts index 1172fdc59d..a63eb8b6e0 100644 --- a/app/client/cypress/support/Pages/HomePage.ts +++ b/app/client/cypress/support/Pages/HomePage.ts @@ -122,7 +122,7 @@ export class HomePage { } public CreateNewApplication() { - cy.get(this._homePageAppCreateBtn).click({ force: true }) + cy.get(this._homePageAppCreateBtn).first().click({ force: true }) cy.wait("@createNewApplication").should( "have.nested.property", "response.body.responseMeta.status", diff --git a/app/client/cypress/support/Pages/JSEditor.ts b/app/client/cypress/support/Pages/JSEditor.ts index 43be9a7178..196bc29385 100644 --- a/app/client/cypress/support/Pages/JSEditor.ts +++ b/app/client/cypress/support/Pages/JSEditor.ts @@ -23,12 +23,34 @@ export class JSEditor { agHelper.WaitUntilEleDisappear(locator._toastMsg, 'created successfully', 1000) } - public CreateJSObject(JSCode: string, paste = true) { + public CreateJSObject(JSCode: string, paste = true, completeReplace = false) { this.NavigateToJSEditor(); - cy.get(locator._codeMirrorTextArea) + + if (!completeReplace) { + cy.get(locator._codeMirrorTextArea) + .first() + .focus() + .type("{downarrow}{downarrow}{downarrow}{downarrow} ") + } + else { + cy.get(locator._codeMirrorTextArea) .first() .focus() - .type("{downarrow}{downarrow}{downarrow}{downarrow} ") + .type("{downarrow}{downarrow}{downarrow}{downarrow}{downarrow}{downarrow}{downarrow}{downarrow}{downarrow}{downarrow}") + .type("{shift}{uparrow}{uparrow}{uparrow}{uparrow}{uparrow}{uparrow}{uparrow}{uparrow}{uparrow}", { force: true }) + .type("{backspace}",{ force: true }); + + // .type("{uparrow}", { force: true }) + // .type("{ctrl}{shift}{downarrow}", { force: true }) + // .type("{del}",{ force: true }); + + // cy.get(locator._codeEditorTarget).contains('export').click().closest(locator._codeEditorTarget) + // .type("{uparrow}", { force: true }) + // .type("{ctrl}{shift}{downarrow}", { force: true }) + // .type("{backspace}",{ force: true }); + //.type("{downarrow}{downarrow}{downarrow}{downarrow}{downarrow}{downarrow}{downarrow}{downarrow}{downarrow}{downarrow} ") + + } cy.get(locator._codeMirrorTextArea) .first() @@ -75,7 +97,9 @@ export class JSEditor { .first() .focus() .type("{uparrow}", { force: true }) - .type("{ctrl}{shift}{downarrow}", { force: true }); + .type("{ctrl}{shift}{downarrow}", { force: true }) + .type("{del}", { force: true }); + cy.focused().then(($cm: any) => { if ($cm.contents != "") { cy.log("The field is not empty"); diff --git a/app/client/cypress/support/commands.js b/app/client/cypress/support/commands.js index 72c25b03d3..b6e1dc0675 100644 --- a/app/client/cypress/support/commands.js +++ b/app/client/cypress/support/commands.js @@ -42,6 +42,7 @@ const chainStart = Symbol(); export const initLocalstorage = () => { cy.window().then((window) => { window.localStorage.setItem("ShowCommentsButtonToolTip", ""); + window.localStorage.setItem("updateDismissed", "true"); }); }; @@ -328,7 +329,7 @@ Cypress.Commands.add("AppSetupForRename", () => { cy.get(homePage.applicationName).click({ force: true }); cy.get(homePage.portalMenuItem) .contains("Edit Name", { matchCase: false }) - .click(); + .click({ force: true }); } }); }); @@ -338,11 +339,12 @@ Cypress.Commands.add("CreateAppForOrg", (orgName, appname) => { .scrollIntoView() .should("be.visible") .click({ force: true }); - cy.wait("@createNewApplication").should( - "have.nested.property", - "response.body.responseMeta.status", - 201, - ); + cy.wait("@createNewApplication").then((xhr) => { + const response = xhr.response; + expect(response.body.responseMeta.status).to.eq(201); + localStorage.setItem("applicationId", response.body.data.id); + }); + cy.get("#loading").should("not.exist"); // eslint-disable-next-line cypress/no-unnecessary-waiting cy.wait(2000); @@ -360,14 +362,16 @@ Cypress.Commands.add("CreateAppForOrg", (orgName, appname) => { }); Cypress.Commands.add("CreateAppInFirstListedOrg", (appname) => { + let applicationId; cy.get(homePage.createNew) .first() .click({ force: true }); - cy.wait("@createNewApplication").should( - "have.nested.property", - "response.body.responseMeta.status", - 201, - ); + cy.wait("@createNewApplication").then((xhr) => { + const response = xhr.response; + expect(response.body.responseMeta.status).to.eq(201); + applicationId = response.body.data.id; + localStorage.setItem("applicationId", applicationId); + }); cy.get("#loading").should("not.exist"); // eslint-disable-next-line cypress/no-unnecessary-waiting cy.wait(2000); @@ -552,6 +556,9 @@ Cypress.Commands.add("DeletepageFromSideBar", () => { cy.get(pages.deletePage) .first() .click({ force: true }); + cy.get(pages.deletePageConfirm) + .first() + .click({ force: true }); // eslint-disable-next-line cypress/no-unnecessary-waiting cy.wait(2000); }); @@ -1120,7 +1127,7 @@ Cypress.Commands.add("MoveAPIToPage", (pageName) => { cy.get(apiwidget.moveTo).click({ force: true }); cy.get(apiwidget.page) .contains(pageName) - .click(); + .click({ force: true }); cy.wait("@moveAction").should( "have.nested.property", "response.body.responseMeta.status", @@ -1135,7 +1142,7 @@ Cypress.Commands.add("copyEntityToPage", (pageName) => { cy.get(apiwidget.copyTo).click({ force: true }); cy.get(apiwidget.page) .contains(pageName) - .click(); + .click({ force: true }); cy.wait("@createNewApi").should( "have.nested.property", "response.body.responseMeta.status", @@ -1224,7 +1231,10 @@ Cypress.Commands.add("DeleteAPIFromSideBar", () => { }); Cypress.Commands.add("DeleteWidgetFromSideBar", () => { - cy.deleteEntity(); + cy.xpath(apiwidget.popover) + .last() + .click({ force: true }); + cy.get(apiwidget.delete).click({ force: true }); cy.wait("@updateLayout").should( "have.nested.property", "response.body.responseMeta.status", @@ -1237,10 +1247,19 @@ Cypress.Commands.add("deleteEntity", () => { .last() .click({ force: true }); cy.get(apiwidget.delete).click({ force: true }); + cy.get(apiwidget.deleteConfirm).click({ force: true }); +}); + +Cypress.Commands.add("deleteEntityWithoutConfirmation", () => { + cy.xpath(apiwidget.popover) + .last() + .click({ force: true }); + cy.get(apiwidget.delete).click({ force: true }); }); Cypress.Commands.add("DeleteAPI", (apiname) => { - cy.get(ApiEditor.ApiActionMenu) + cy.get(ApiEditor.ApiActionMenu).click({ multiple: true }); + cy.get(apiwidget.deleteAPI) .first() .click({ force: true }); cy.get(apiwidget.deleteAPI) @@ -1430,7 +1449,6 @@ Cypress.Commands.add("PublishtheApp", () => { cy.get(homePage.publishButton).click(); cy.wait("@publishApp"); - cy.url().should("include", "/pages"); cy.log("pagename: " + localStorage.getItem("PageName")); cy.wait(1000); //wait time for page to load! }); @@ -1680,6 +1698,16 @@ Cypress.Commands.add("deleteColumn", (colId) => { cy.wait(1000); }); +Cypress.Commands.add("openFieldConfiguration", (fieldIdentifier) => { + cy.get( + "[data-rbd-draggable-id='" + fieldIdentifier + "'] .t--edit-column-btn", + ).click({ + force: true, + }); + // eslint-disable-next-line cypress/no-unnecessary-waiting + cy.wait(1000); +}); + Cypress.Commands.add("makeColumnVisible", (colId) => { cy.get("[data-rbd-draggable-id='" + colId + "'] .t--show-column-btn").click({ force: true, @@ -1849,51 +1877,37 @@ Cypress.Commands.add("DeleteModal", () => { .click({ force: true }); }); -Cypress.Commands.add("Createpage", (Pagename) => { +Cypress.Commands.add("Createpage", (pageName) => { + let pageId; cy.get(pages.AddPage) .first() .click({ force: true }); - cy.wait("@createPage").should( - "have.nested.property", - "response.body.responseMeta.status", - 201, - ); - // eslint-disable-next-line cypress/no-unnecessary-waiting - cy.wait(2000); - cy.xpath(apiwidget.popover) - .last() - .should("be.hidden") - .invoke("show") - .click({ force: true }); - cy.xpath(apiwidget.popover) - .last() - .click({ force: true }); - /* - cy.xpath(pages.popover) - .last() - .click({ force: true }); - */ - cy.get(pages.editName).click({ force: true }); - cy.get(pages.editInput).type(Pagename + "{enter}"); - pageidcopy = Pagename; - cy.get(generatePage.buildFromScratchActionCard).click(); - cy.get("#loading").should("not.exist"); - // eslint-disable-next-line cypress/no-unnecessary-waiting - cy.wait(2000); + cy.wait("@createPage").then((xhr) => { + expect(xhr.response.body.responseMeta.status).to.equal(201); + if (pageName) { + pageId = xhr.response.body.data.id; + cy.wait(2000); + cy.get(`div[id=entity-${pageId}] .t--context-menu`).click({ + force: true, + }); + cy.get(pages.editName).click({ force: true }); + cy.get(pages.editInput).type(pageName + "{enter}"); + pageidcopy = pageName; + } + cy.get(generatePage.buildFromScratchActionCard).click(); + cy.get("#loading").should("not.exist"); + }); }); Cypress.Commands.add("Deletepage", (Pagename) => { - cy.get(pages.pagesIcon).click({ force: true }); - cy.get(".t--page-sidebar-" + Pagename + ""); - cy.get( - ".t--page-sidebar-" + - Pagename + - ">.t--page-sidebar-menu-actions>.bp3-popover-target", - ).click({ force: true }); - cy.get(pages.Menuaction).click({ force: true }); - cy.get(pages.Delete).click({ force: true }); - // eslint-disable-next-line cypress/no-unnecessary-waiting - cy.wait(2000); + cy.CheckAndUnfoldEntityItem("PAGES"); + cy.get(`.t--entity-item:contains(${Pagename})`).within(() => { + cy.get(".t--context-menu").click({ force: true }); + }); + cy.selectAction("Delete"); + cy.selectAction("Are you sure?"); + cy.wait("@deletePage"); + cy.get("@deletePage").should("have.property", "status", 200); }); Cypress.Commands.add("generateUUID", () => { @@ -1908,13 +1922,13 @@ Cypress.Commands.add("addDsl", (dsl) => { let layoutId; cy.url().then((url) => { currentURL = url; - const myRegexp = /pages(.*)/; - const match = myRegexp.exec(currentURL); - pageid = match[1].split("/")[1]; + pageid = currentURL + .split("/")[4] + ?.split("-") + .pop(); cy.log(pageidcopy + "page id copy"); cy.log(pageid + "page id"); //Fetch the layout id - cy.server(); cy.request("GET", "api/v1/pages/" + pageid).then((response) => { const respBody = JSON.stringify(response.body); layoutId = JSON.parse(respBody).data.layouts[0].id; @@ -1933,26 +1947,18 @@ Cypress.Commands.add("addDsl", (dsl) => { }); Cypress.Commands.add("DeleteAppByApi", () => { - let currentURL; - let appId; - cy.url().then((url) => { - currentURL = url; - const myRegexp = /applications(.*)/; - const match = myRegexp.exec(currentURL); - appId = match ? match[1].split("/")[1] : null; - - if (appId !== null) { - cy.log(appId + "appId"); - cy.request({ - method: "DELETE", - url: "api/v1/applications/" + appId, - failOnStatusCode: false, - }).then((response) => { - cy.log(response.body); - cy.log(response.status); - }); - } - }); + const appId = localStorage.getItem("applicationId"); + if (appId !== null) { + cy.log(appId + "appId"); + cy.request({ + method: "DELETE", + url: "api/v1/applications/" + appId, + failOnStatusCode: false, + }).then((response) => { + cy.log(response.body); + cy.log(response.status); + }); + } }); Cypress.Commands.add("togglebar", (value) => { @@ -2074,6 +2080,19 @@ Cypress.Commands.add( }, ); +Cypress.Commands.add("typeIntoDraftEditor", (selector, text) => { + cy.get(selector).then((input) => { + var textarea = input.get(0); + textarea.dispatchEvent(new Event("focus")); + + var textEvent = document.createEvent("TextEvent"); + textEvent.initTextEvent("textInput", true, true, null, text); + textarea.dispatchEvent(textEvent); + + textarea.dispatchEvent(new Event("blur")); + }); +}); + Cypress.Commands.add("addQueryFromLightningMenu", (QueryName) => { cy.get(commonlocators.dropdownSelectButton) .first() @@ -2179,7 +2198,9 @@ Cypress.Commands.add("testSaveDeleteDatasource", () => { .click(); // delete datasource cy.get(".t--delete-datasource").click(); - cy.get("[data-cy=t--confirm-modal-btn]").click(); + cy.get(".t--delete-datasource") + .contains("Are you sure?") + .click(); cy.wait("@deleteDatasource").should( "have.nested.property", "response.body.responseMeta.status", @@ -2255,7 +2276,7 @@ Cypress.Commands.add("ClickGotIt", () => { }); Cypress.Commands.add("testDatasource", (expectedRes = true) => { - cy.get(".t--test-datasource").click(); + cy.get(".t--test-datasource").click({ force: true }); cy.wait("@testDatasource").should( "have.nested.property", "response.body.data.success", @@ -2264,7 +2285,7 @@ Cypress.Commands.add("testDatasource", (expectedRes = true) => { }); Cypress.Commands.add("saveDatasource", () => { - cy.get(".t--save-datasource").click(); + cy.get(".t--save-datasource").click({ force: true }); cy.wait("@saveDatasource") .then((xhr) => { cy.log(JSON.stringify(xhr.response.body)); @@ -2290,16 +2311,16 @@ Cypress.Commands.add( const hostAddress = shouldAddTrailingSpaces ? datasourceFormData["mongo-host"] + " " : datasourceFormData["mongo-host"]; - const databaseName = shouldAddTrailingSpaces - ? datasourceFormData["mongo-databaseName"] + " " - : datasourceFormData["mongo-databaseName"]; + // const databaseName = shouldAddTrailingSpaces + // ? datasourceFormData["mongo-databaseName"] + " " + // : datasourceFormData["mongo-databaseName"]; cy.get(datasourceEditor["host"]).type(hostAddress); cy.get(datasourceEditor.port).type(datasourceFormData["mongo-port"]); //cy.get(datasourceEditor["port"]).type(datasourceFormData["mongo-port"]); //cy.get(datasourceEditor["selConnectionType"]).click(); //cy.contains(datasourceFormData["connection-type"]).click(); - cy.get(datasourceEditor["defaultDatabaseName"]).type(databaseName); + //cy.get(datasourceEditor["defaultDatabaseName"]).type(databaseName);//is optional hence removing cy.get(datasourceEditor.sectionAuthentication).click(); cy.get(datasourceEditor["databaseName"]) @@ -2318,6 +2339,11 @@ Cypress.Commands.add( }, ); +Cypress.Commands.add("fillAuthenticatedAPIForm", () => { + const URL = datasourceFormData["authenticatedApiUrl"]; + cy.get(datasourceEditor.url).type(URL); +}); + Cypress.Commands.add( "fillPostgresDatasourceForm", (shouldAddTrailingSpaces = false) => { @@ -2511,7 +2537,9 @@ Cypress.Commands.add("deleteDatasource", (datasourceName) => { .click({ force: true }); cy.contains(".t--datasource-name", datasourceName).click(); cy.get(".t--delete-datasource").click(); - cy.get("[data-cy=t--confirm-modal-btn]").click(); + cy.get(".t--delete-datasource") + .contains("Are you sure?") + .click(); cy.wait("@deleteDatasource").should( "have.nested.property", "response.body.responseMeta.status", @@ -2563,6 +2591,7 @@ Cypress.Commands.add("hoverAndClickParticularIndex", (index) => { Cypress.Commands.add("deleteQuery", () => { cy.hoverAndClick(); cy.get(apiwidget.delete).click({ force: true }); + cy.get(apiwidget.deleteConfirm).click({ force: true }); cy.wait("@deleteAction").should( "have.nested.property", "response.body.responseMeta.status", @@ -2576,9 +2605,15 @@ Cypress.Commands.add("selectAction", (option) => { .click({ force: true }); }); +Cypress.Commands.add("deleteActionAndConfirm", () => { + cy.selectAction("Delete"); + cy.selectAction("Are you sure?"); +}); + Cypress.Commands.add("deleteJSObject", () => { cy.hoverAndClick(); cy.get(jsEditorLocators.delete).click({ force: true }); + cy.get(jsEditorLocators.deleteConfirm).click({ force: true }); cy.wait("@deleteJSCollection").should( "have.nested.property", "response.body.responseMeta.status", @@ -2589,7 +2624,7 @@ Cypress.Commands.add("deleteJSObject", () => { Cypress.Commands.add("deleteDataSource", () => { cy.hoverAndClick(); cy.get(apiwidget.delete).click({ force: true }); - cy.get("[data-cy=t--confirm-modal-btn]").click(); + cy.get(apiwidget.deleteConfirm).click({ force: true }); cy.wait("@deleteDatasource").should( "have.nested.property", "response.body.responseMeta.status", @@ -2598,8 +2633,13 @@ Cypress.Commands.add("deleteDataSource", () => { }); Cypress.Commands.add("deleteQueryUsingContext", () => { - cy.get(queryEditor.queryMoreAction).click(); + cy.get(queryEditor.queryMoreAction) + .first() + .click(); cy.get(queryEditor.deleteUsingContext).click(); + cy.get(queryEditor.deleteUsingContext) + .contains("Are you sure?") + .click(); cy.wait("@deleteAction").should( "have.nested.property", "response.body.responseMeta.status", @@ -2928,8 +2968,8 @@ Cypress.Commands.add("startServerAndRoutes", () => { cy.route("POST", "/api/v1/logout").as("postLogout"); cy.route("GET", "/api/v1/datasources?organizationId=*").as("getDataSources"); - cy.route("GET", "/api/v1/pages/application/*").as("getPagesForCreateApp"); - cy.route("GET", "/api/v1/applications/view/*").as("getPagesForViewApp"); + cy.route("GET", "/api/v1/pages?*mode=EDIT").as("getPagesForCreateApp"); + cy.route("GET", "/api/v1/pages?*mode=PUBLISHED").as("getPagesForViewApp"); cy.route("POST"); cy.route("GET", "/api/v1/pages/*").as("getPage"); @@ -2939,6 +2979,7 @@ Cypress.Commands.add("startServerAndRoutes", () => { cy.route("GET", "api/v1/import/templateCollections").as( "getTemplateCollections", ); + cy.route("PUT", "/api/v1/pages/*").as("updatePage"); cy.route("DELETE", "/api/v1/actions/*").as("deleteAPI"); cy.route("DELETE", "/api/v1/applications/*").as("deleteApp"); cy.route("DELETE", "/api/v1/actions/*").as("deleteAction"); @@ -2993,6 +3034,7 @@ Cypress.Commands.add("startServerAndRoutes", () => { cy.route("GET", "/api/v1/users/me").as("getUser"); cy.route("POST", "/api/v1/pages").as("createPage"); cy.route("POST", "/api/v1/pages/clone/*").as("clonePage"); + cy.route("POST", "/api/v1/applications/clone/*").as("cloneApp"); cy.route("PUT", "/api/v1/applications/*/changeAccess").as("changeAccess"); cy.route("PUT", "/api/v1/organizations/*").as("updateOrganization"); @@ -3130,7 +3172,7 @@ Cypress.Commands.add("assertEvaluatedValuePopup", (expectedType) => { }); Cypress.Commands.add("validateToastMessage", (value) => { - cy.get(commonlocators.toastMsg).should("have.text", value); + cy.get(commonlocators.toastMsg).should("contain.text", value); }); Cypress.Commands.add("NavigateToPaginationTab", () => { @@ -3481,6 +3523,29 @@ Cypress.Commands.add("skipCommentsOnboarding", () => { cy.get("button[type='submit']").click(); }); +Cypress.Commands.add("revokeAccessGit", (appName) => { + cy.xpath("//span[text()= `${appName}`]") + .parent() + .next() + .click(); + cy.get(gitSyncLocators.disconnectAppNameInput).type(appName); + cy.get(gitSyncLocators.disconnectButton).click(); + cy.route("POST", "api/v1/git/disconnect/*").as("disconnect"); + cy.get(gitSyncLocators.disconnectButton).click(); + cy.wait("@disconnect").should( + "have.nested.property", + "response.body.responseMeta.status", + 200, + ); + cy.window() + .its("store") + .invoke("getState") + .then((state) => { + const { id, name } = state.ui.gitSync.disconnectingGitApp; + expect(name).to.eq(""); + expect(id).to.eq(""); + }); +}); Cypress.Commands.add( "connectToGitRepo", (repo, shouldCommit = true, assertConnectFailure) => { @@ -3802,7 +3867,7 @@ Cypress.Commands.add("clickButton", (btnVisibleText) => { Cypress.Commands.add( "actionContextMenuByEntityName", - (entityNameinLeftSidebar, action = "Delete") => { + (entityNameinLeftSidebar, action = "Delete", subAction) => { cy.wait(2000); // cy.get( // commonlocators.entitySearchResult @@ -3827,11 +3892,21 @@ Cypress.Commands.add( cy.xpath( "//div[text()='" + action + - "']/parent::a[contains(@class, 'single-select')]", + "']/ancestor::a[contains(@class, 'single-select')]", ) .click({ force: true }) .wait(500); + if (subAction) { + cy.xpath( + "//div[text()='" + + subAction + + "']/parent::a[contains(@class, 'single-select')]", + ) + .click({ force: true }) + .wait(500); + } + if (action === "Delete") cy.xpath("//div[text()='" + entityNameinLeftSidebar + "']").should( "not.exist", @@ -3875,13 +3950,15 @@ Cypress.Commands.add( }, ); +// Cypress >=8.3.x onwards cy.all = function(...commands) { const _ = Cypress._; + // eslint-disable-next-line const chain = cy.wrap(null, { log: false }); - const stopCommand = _.find(cy.queue.commands, { + const stopCommand = _.find(cy.queue.get(), { attributes: { chainerId: chain.chainerId }, }); - const startCommand = _.find(cy.queue.commands, { + const startCommand = _.find(cy.queue.get(), { attributes: { chainerId: commands[0].chainerId }, }); const p = chain.then(() => { @@ -3889,7 +3966,7 @@ cy.all = function(...commands) { .map((cmd) => { return cmd[chainStart] ? cmd[chainStart].attributes - : _.find(cy.queue.commands, { + : _.find(cy.queue.get(), { attributes: { chainerId: cmd.chainerId }, }).attributes; }) diff --git a/app/client/cypress/support/index.js b/app/client/cypress/support/index.js index d1adbb7ad5..beac3774c5 100644 --- a/app/client/cypress/support/index.js +++ b/app/client/cypress/support/index.js @@ -19,7 +19,8 @@ import "cypress-xpath"; import "cypress-wait-until"; /// -let appId; +let appName; +let applicationId; // Import commands.js using ES2015 syntax: import "./commands"; @@ -79,9 +80,8 @@ before(function() { cy.get(".t--applications-container .createnew").should("be.visible"); cy.get(".t--applications-container .createnew").should("be.enabled"); cy.generateUUID().then((id) => { - appId = id; cy.CreateAppInFirstListedOrg(id); - localStorage.setItem("AppName", appId); + localStorage.setItem("AppName", id); }); cy.fixture("example").then(function(data) { diff --git a/app/client/package.json b/app/client/package.json index 67b81c62f7..811fdf8917 100644 --- a/app/client/package.json +++ b/app/client/package.json @@ -73,7 +73,7 @@ "lint-staged": "^9.2.5", "localforage": "^1.7.3", "lodash": "^4.17.21", - "lodash-es": "4.17.14", + "lodash-es": "4.17.21", "lodash-move": "^1.1.1", "loglevel": "^1.7.1", "lottie-web": "^5.7.4", @@ -89,7 +89,8 @@ "path-to-regexp": "^6.2.0", "popper.js": "^1.15.0", "prettier": "^1.18.2", - "prismjs": "^1.25.0", + "prismjs": "^1.27.0", + "punycode": "^2.1.1", "rc-pagination": "^3.1.3", "rc-select": "^12.1.10", "rc-tree-select": "^4.4.0-alpha.2", @@ -108,6 +109,7 @@ "react-google-maps": "^9.4.5", "react-google-recaptcha": "^2.1.0", "react-helmet": "^5.2.1", + "react-hook-form": "^7.28.0", "react-infinite-scroller": "^1.2.4", "react-instantsearch-dom": "^6.4.0", "react-json-view": "^1.19.1", @@ -256,7 +258,7 @@ "cra-bundle-analyzer": "^0.1.0", "craco-babel-loader": "^0.1.4", "cy-verify-downloads": "^0.0.5", - "cypress": "7.6.0", + "cypress": "8.7.0", "cypress-file-upload": "^4.1.1", "cypress-image-snapshot": "^4.0.1", "cypress-multi-reporters": "^1.2.4", @@ -278,8 +280,8 @@ "jest-canvas-mock": "^2.3.1", "mocha": "^7.1.0", "mocha-junit-reporter": "^1.23.3", - "mochawesome": "^5.0.0", - "mochawesome-report-generator": "^4.1.0", + "mochawesome": "^7.1.2", + "mochawesome-report-generator": "^6.1.1", "msw": "^0.28.0", "patch-package": "^6.4.7", "plop": "^2.7.4", diff --git a/app/client/perf/package.json b/app/client/perf/package.json index b5980b517f..fc03bc4cf2 100644 --- a/app/client/perf/package.json +++ b/app/client/perf/package.json @@ -12,7 +12,7 @@ "@supabase/supabase-js": "^1.30.2", "median": "^0.0.2", "node-stdev": "^1.0.1", - "puppeteer": "^12.0.1", + "puppeteer": "^13.5.1", "sanitize-filename": "^1.6.3", "tracelib": "^1.0.1" } diff --git a/app/client/perf/src/perf.js b/app/client/perf/src/perf.js index 430fa40a27..efd87bfbb2 100644 --- a/app/client/perf/src/perf.js +++ b/app/client/perf/src/perf.js @@ -109,9 +109,7 @@ module.exports = class Perf { await this.page.waitForNavigation(); const currentUrl = this.page.url(); - const pageIdRegex = /pages(.*)/; - const match = pageIdRegex.exec(currentUrl); - const pageId = match[1].split("/")[1]; + const pageId = currentURL.split("/")[4]?.split("-").pop(); await this.page.evaluate( async ({ pageId, dsl }) => { diff --git a/app/client/perf/yarn.lock b/app/client/perf/yarn.lock index bbff1e76a0..2e19714aa0 100644 --- a/app/client/perf/yarn.lock +++ b/app/client/perf/yarn.lock @@ -124,7 +124,7 @@ concat-map@0.0.1: resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= -cross-fetch@^3.0.6, cross-fetch@^3.1.0: +cross-fetch@3.1.5, cross-fetch@^3.0.6, cross-fetch@^3.1.0: version "3.1.5" resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.5.tgz#e1389f44d9e7ba767907f7af8454787952ab534f" integrity sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw== @@ -139,20 +139,13 @@ d@1, d@^1.0.1: es5-ext "^0.10.50" type "^1.0.1" -debug@4, debug@^4.1.1: +debug@4, debug@4.3.3, debug@^4.1.1: version "4.3.3" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== dependencies: ms "2.1.2" -debug@4.3.2: - version "4.3.2" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" - integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== - dependencies: - ms "2.1.2" - debug@^2.2.0: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" @@ -160,10 +153,10 @@ debug@^2.2.0: dependencies: ms "2.0.0" -devtools-protocol@0.0.937139: - version "0.0.937139" - resolved "https://registry.yarnpkg.com/devtools-protocol/-/devtools-protocol-0.0.937139.tgz#bdee3751fdfdb81cb701fd3afa94b1065dafafcf" - integrity sha512-daj+rzR3QSxsPRy5vjjthn58axO8c11j58uY0lG5vvlJk/EiOdCWOptGdkXDjtuRHr78emKq0udHCXM4trhoDQ== +devtools-protocol@0.0.969999: + version "0.0.969999" + resolved "https://registry.yarnpkg.com/devtools-protocol/-/devtools-protocol-0.0.969999.tgz#3d6be0a126b3607bb399ae2719b471dda71f3478" + integrity sha512-6GfzuDWU0OFAuOvBokXpXPLxjOJ5DZ157Ue3sGQQM3LgAamb8m0R0ruSfN0DDu+XG5XJgT50i6zZ/0o8RglreQ== end-of-stream@^1.1.0, end-of-stream@^1.4.1: version "1.4.4" @@ -335,13 +328,6 @@ next-tick@~1.0.0: resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" integrity sha1-yobR/ogoFpsBICCOPchCS524NCw= -node-fetch@2.6.5: - version "2.6.5" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.5.tgz#42735537d7f080a7e5f78b6c549b7146be1742fd" - integrity sha512-mmlIVHJEu5rnIxgEgez6b9GgWXbkZj5YZ7fx+2r94a2E+Uirsp6HsPTPlomfdHtpt/B0cdKviwkoaM6pyvUOpQ== - dependencies: - whatwg-url "^5.0.0" - node-fetch@2.6.7: version "2.6.7" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" @@ -427,23 +413,23 @@ pump@^3.0.0: end-of-stream "^1.1.0" once "^1.3.1" -puppeteer@^12.0.1: - version "12.0.1" - resolved "https://registry.yarnpkg.com/puppeteer/-/puppeteer-12.0.1.tgz#ae79d0e174a07563e0bf2e05c94ccafce3e70033" - integrity sha512-YQ3GRiyZW0ddxTW+iiQcv2/8TT5c3+FcRUCg7F8q2gHqxd5akZN400VRXr9cHQKLWGukmJLDiE72MrcLK9tFHQ== +puppeteer@^13.5.1: + version "13.5.1" + resolved "https://registry.yarnpkg.com/puppeteer/-/puppeteer-13.5.1.tgz#d0f751bf36120efc2ebf74c7562a204a84e500e9" + integrity sha512-wWxO//vMiqxlvuzHMAJ0pRJeDHvDtM7DQpW1GKdStz2nZo2G42kOXBDgkmQ+zqjwMCFofKGesBeeKxIkX9BO+w== dependencies: - debug "4.3.2" - devtools-protocol "0.0.937139" + cross-fetch "3.1.5" + debug "4.3.3" + devtools-protocol "0.0.969999" extract-zip "2.0.1" https-proxy-agent "5.0.0" - node-fetch "2.6.5" pkg-dir "4.2.0" progress "2.0.3" proxy-from-env "1.1.0" rimraf "3.0.2" tar-fs "2.1.1" unbzip2-stream "1.4.3" - ws "8.2.3" + ws "8.5.0" readable-stream@^3.1.1, readable-stream@^3.4.0: version "3.6.0" @@ -595,10 +581,10 @@ wrappy@1: resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= -ws@8.2.3: - version "8.2.3" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.2.3.tgz#63a56456db1b04367d0b721a0b80cae6d8becbba" - integrity sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA== +ws@8.5.0: + version "8.5.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.5.0.tgz#bfb4be96600757fe5382de12c670dab984a1ed4f" + integrity sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg== yaeti@^0.0.6: version "0.0.6" diff --git a/app/client/src/AppRouter.tsx b/app/client/src/AppRouter.tsx index 53207c8a21..77fbbf566b 100644 --- a/app/client/src/AppRouter.tsx +++ b/app/client/src/AppRouter.tsx @@ -1,4 +1,4 @@ -import React, { Suspense } from "react"; +import React, { Suspense, useEffect } from "react"; import history from "utils/history"; import AppHeader from "pages/common/AppHeader"; import { Redirect, Route, Router, Switch } from "react-router-dom"; @@ -8,7 +8,7 @@ import { BASE_LOGIN_URL, BASE_SIGNUP_URL, BASE_URL, - BUILDER_URL, + BUILDER_PATH, ORG_URL, SIGN_UP_URL, SIGNUP_SUCCESS_URL, @@ -17,11 +17,13 @@ import { PROFILE, UNSUBSCRIBE_EMAIL_URL, SETUP, - VIEWER_URL, - ADMIN_SETTINGS_URL, - ADMIN_SETTINGS_CATEGORY_URL, - ADMIN_SETTINGS_CATEGORY_DEFAULT_URL, - TEMPLATES_URL, + VIEWER_PATH, + ADMIN_SETTINGS_PATH, + ADMIN_SETTINGS_CATEGORY_PATH, + ADMIN_SETTINGS_CATEGORY_DEFAULT_PATH, + BUILDER_PATH_DEPRECATED, + VIEWER_PATH_DEPRECATED, + TEMPLATES_PATH, } from "constants/routes"; import OrganizationLoader from "pages/organization/loader"; import ApplicationListLoader from "pages/Applications/loader"; @@ -50,6 +52,8 @@ import { getFeatureFlagsFetched } from "selectors/usersSelectors"; import Setup from "pages/setup"; import Settings from "pages/Settings"; import SignupSuccess from "pages/setup/SignupSuccess"; +import { Theme } from "constants/DefaultTheme"; +import { ERROR_CODES } from "ce/constants/ApiConstants"; import TemplatesListLoader from "pages/Templates/loader"; import getFeatureFlags from "utils/featureFlags"; @@ -71,99 +75,101 @@ function changeAppBackground(currentTheme: any) { } } -class AppRouter extends React.Component { - unlisten: any; - - componentDidMount() { - // This is needed for the route switch. +function AppRouter(props: { + safeCrash: boolean; + getCurrentUser: () => void; + currentTheme: Theme; + featureFlagsFetched: boolean; + safeCrashCode?: ERROR_CODES; + setTheme: (theme: ThemeMode) => void; +}) { + useEffect(() => { AnalyticsUtil.logEvent("ROUTE_CHANGE", { path: window.location.pathname }); - this.unlisten = history.listen((location: any) => { + const stopListener = history.listen((location: any) => { AnalyticsUtil.logEvent("ROUTE_CHANGE", { path: location.pathname }); - changeAppBackground(this.props.currentTheme); + changeAppBackground(props.currentTheme); }); - this.props.getCurrentUser(); - } + props.getCurrentUser(); - componentWillUnmount() { - this.unlisten(); - } + return stopListener; + }, []); - render() { - const { - currentTheme, - featureFlagsFetched, - safeCrash, - safeCrashCode, - } = this.props; + useEffect(() => { + changeAppBackground(props.currentTheme); + }, [props.currentTheme]); - // This is needed for the theme switch. - changeAppBackground(currentTheme); + if (!props.featureFlagsFetched) return null; - // Render the app once the feature flags have been fetched - if (!featureFlagsFetched) return null; + return ( + + + {props.safeCrash && props.safeCrashCode ? ( + <> + + + + ) : ( + <> + + + + + + + + + + - return ( - - - {safeCrash ? ( - <> - - - - ) : ( - <> - - - - - - - - + + + + {getFeatureFlags().APP_TEMPLATE && ( - {getFeatureFlags().APP_TEMPLATE && ( - - )} - - - - - - - - - - - - - )} - - - ); - } + )} + + + + + + + + + + )} + + + ); } + const mapStateToProps = (state: AppState) => ({ currentTheme: getCurrentThemeDetails(state), safeCrash: getSafeCrash(state), diff --git a/app/client/src/RouteBuilder.ts b/app/client/src/RouteBuilder.ts new file mode 100644 index 0000000000..bcb5257b5e --- /dev/null +++ b/app/client/src/RouteBuilder.ts @@ -0,0 +1,299 @@ +import { + ADMIN_SETTINGS_PATH, + BUILDER_PATH, + BUILDER_PATH_DEPRECATED, + GEN_TEMPLATE_FORM_ROUTE, + GEN_TEMPLATE_URL, + PLACEHOLDER_APP_SLUG, + PLACEHOLDER_PAGE_SLUG, + TEMPLATES_PATH, + VIEWER_PATH, + VIEWER_PATH_DEPRECATED, +} from "constants/routes"; +import { APP_MODE } from "entities/App"; +import getQueryParamsObject from "utils/getQueryParamsObject"; +import { matchPath } from "react-router"; +import { ApplicationVersion } from "actions/applicationActions"; + +export function convertToQueryParams( + params: Record = {}, +): string { + const paramKeys = Object.keys(params); + const queryParams: string[] = []; + if (paramKeys) { + paramKeys.forEach((paramKey: string) => { + const value = params[paramKey]; + if (paramKey && value) { + queryParams.push(`${paramKey}=${value}`); + } + }); + } + return queryParams.length ? "?" + queryParams.join("&") : ""; +} + +const fetchParamsToPersist = () => { + const existingParams = getQueryParamsObject() || {}; + // not persisting the entire query currently, since that's the current behaviour + const { branch, embed } = existingParams; + let params = { branch, embed } as any; + // test param to make sure a query param is present in the URL during dev and tests + if ((window as any).Cypress) { + params = { a: "b", ...params }; + } + return params; +}; + +type Optional = { + [K in keyof T]+?: T[K]; +}; + +type BaseURLBuilderParams = { + applicationId: string; + applicationSlug: string; + pageId: string; + pageSlug: string; + applicationVersion?: ApplicationVersion; +}; + +type URLBuilderParams = BaseURLBuilderParams & { + suffix: string; + branch: string; + hash: string; + params: Record; +}; + +export const DEFAULT_BASE_URL_BUILDER_PARAMS: BaseURLBuilderParams = { + applicationId: "", + applicationSlug: "", + pageId: "", + pageSlug: "", +}; + +/** + * This variable is private to this module and should not be exported. + * This variable holds the information essential for url building, (current applicationId, pageId, pageSlug and applicationSlug ), + * updateURLFactory method is used to update this variable in a middleware. Refer /store.ts. + * */ +let BASE_URL_BUILDER_PARAMS = DEFAULT_BASE_URL_BUILDER_PARAMS; + +export function updateURLFactory(params: Optional) { + BASE_URL_BUILDER_PARAMS = { ...BASE_URL_BUILDER_PARAMS, ...params }; +} + +/** + * Do not export this method directly. Please write wrappers for your URLs. + * Uses applicationVersion attribute to determine whether to use slug URLs or legacy URLs. + */ +function baseURLBuilder( + { + applicationId, + applicationSlug, + applicationVersion, + pageId, + pageSlug, + ...rest + }: Optional, + mode: APP_MODE = APP_MODE.EDIT, +): string { + const { hash = "", params = {}, suffix } = { ...rest }; + applicationVersion = + applicationVersion || BASE_URL_BUILDER_PARAMS.applicationVersion; + const shouldUseLegacyURLs = + typeof applicationVersion !== "undefined" && + applicationVersion < ApplicationVersion.SLUG_URL; + + let basePath = ""; + pageId = pageId || BASE_URL_BUILDER_PARAMS.pageId; + + // fallback incase pageId is not set + if (!pageId) { + const match = matchPath<{ pageId: string }>(window.location.pathname, { + path: [ + BUILDER_PATH, + BUILDER_PATH_DEPRECATED, + VIEWER_PATH, + VIEWER_PATH_DEPRECATED, + ], + strict: false, + exact: false, + }); + pageId = match?.params.pageId; + } + // fallback incase pageId is not set + + if (shouldUseLegacyURLs) { + applicationId = applicationId || BASE_URL_BUILDER_PARAMS.applicationId; + basePath = `/applications/${applicationId}/pages/${pageId}`; + } else { + applicationSlug = + applicationSlug || + BASE_URL_BUILDER_PARAMS.applicationSlug || + PLACEHOLDER_APP_SLUG; + pageSlug = + pageSlug || BASE_URL_BUILDER_PARAMS.pageSlug || PLACEHOLDER_PAGE_SLUG; + basePath = `/${applicationSlug}/${pageSlug}-${pageId}`; + } + basePath += mode === APP_MODE.EDIT ? "/edit" : ""; + + const paramsToPersist = fetchParamsToPersist(); + const modifiedParams = { ...paramsToPersist, ...params }; + const queryString = convertToQueryParams(modifiedParams); + const suffixPath = suffix ? `/${suffix}` : ""; + const hashPath = hash ? `#${hash}` : ""; + + // hash fragment should be at the end of the href + // ref: https://www.rfc-editor.org/rfc/rfc3986#section-4.1 + return `${basePath}${suffixPath}${queryString}${hashPath}`; +} + +export const pageListEditorURL = ( + props?: Optional, +): string => { + return baseURLBuilder({ + ...props, + suffix: "pages", + }); +}; +export const datasourcesEditorURL = ( + props?: Optional, +): string => + baseURLBuilder({ + ...props, + suffix: "datasource", + }); + +export const datasourcesEditorIdURL = ( + props: Optional & { + datasourceId: string; + }, +): string => { + return baseURLBuilder({ + ...props, + suffix: `datasource/${props.datasourceId}`, + }); +}; + +export const jsCollectionIdURL = ( + props: Optional & { + collectionId: string; + }, +): string => { + return baseURLBuilder({ + ...props, + suffix: `jsObjects/${props.collectionId}`, + }); +}; + +export const integrationEditorURL = ( + props: Optional & { selectedTab: string }, +): string => { + const suffixPath = props.suffix ? `/${props.suffix}` : ""; + return baseURLBuilder({ + ...props, + suffix: `datasources/${props.selectedTab}${suffixPath}`, + }); +}; + +export const queryEditorIdURL = ( + props: Optional & { + queryId: string; + }, +): string => + baseURLBuilder({ + ...props, + suffix: `queries/${props.queryId}`, + }); + +export const apiEditorIdURL = ( + props: Optional & { + apiId: string; + }, +): string => + baseURLBuilder({ + ...props, + suffix: `api/${props.apiId}`, + }); + +export const curlImportPageURL = (props?: Optional): string => + baseURLBuilder({ + ...props, + suffix: "api/curl/curl-import", + }); + +export const providerTemplatesURL = ({ + providerId, +}: Optional & { + providerId: string; +}): string => + baseURLBuilder({ + suffix: `api/provider/${providerId}`, + }); + +export const saasEditorDatasourceIdURL = ( + props: Optional & { + pluginPackageName: string; + datasourceId: string; + }, +): string => + baseURLBuilder({ + ...props, + suffix: `saas/${props.pluginPackageName}/datasources/${props.datasourceId}`, + }); + +export const saasEditorApiIdURL = ( + props: Optional & { + pluginPackageName: string; + apiId: string; + }, +): string => + baseURLBuilder({ + ...props, + suffix: `saas/${props.pluginPackageName}/api/${props.apiId}`, + }); + +export const generateTemplateURL = ( + props?: Optional, +): string => + baseURLBuilder({ + ...props, + suffix: GEN_TEMPLATE_URL, + }); + +export const generateTemplateFormURL = ( + props?: Optional, +): string => + baseURLBuilder({ + ...props, + suffix: `${GEN_TEMPLATE_URL}${GEN_TEMPLATE_FORM_ROUTE}`, + }); + +export const onboardingCheckListUrl = ( + props?: Optional, +): string => + baseURLBuilder({ + ...props, + suffix: "checklist", + }); + +export const builderURL = (props?: Optional): string => { + return baseURLBuilder({ ...props }); +}; + +export const viewerURL = (props?: Optional): string => { + return baseURLBuilder({ ...props }, APP_MODE.PUBLISHED); +}; + +export function adminSettingsCategoryUrl({ + category, + subCategory, +}: { + category: string; + subCategory?: string; +}) { + return `${ADMIN_SETTINGS_PATH}/${category}${ + subCategory ? "/" + subCategory : "" + }`; +} + +export const templateIdUrl = ({ id }: { id: string }): string => + `${TEMPLATES_PATH}/${id}`; diff --git a/app/client/src/actions/apiPaneActions.ts b/app/client/src/actions/apiPaneActions.ts index b2155554ca..caa6de8e71 100644 --- a/app/client/src/actions/apiPaneActions.ts +++ b/app/client/src/actions/apiPaneActions.ts @@ -77,16 +77,14 @@ export const updateBodyContentType = ( }); export const redirectToNewIntegrations = ( - applicationId: string, pageId: string, params?: any, ): ReduxAction<{ - applicationId: string; pageId: string; params: any; }> => ({ type: ReduxActionTypes.REDIRECT_TO_NEW_INTEGRATIONS, - payload: { applicationId, pageId, params }, + payload: { pageId, params }, }); export const executeCommandAction = (payload: SlashCommandPayload) => ({ diff --git a/app/client/src/actions/applicationActions.ts b/app/client/src/actions/applicationActions.ts index 71be81237e..43b6387187 100644 --- a/app/client/src/actions/applicationActions.ts +++ b/app/client/src/actions/applicationActions.ts @@ -1,15 +1,16 @@ import { ReduxActionTypes } from "constants/ReduxActionConstants"; -import { APP_MODE } from "entities/App"; -import { - ReduxActionErrorTypes, - ReduxActionWithCallbacks, -} from "../constants/ReduxActionConstants"; -import { FetchApplicationResponse } from "../api/ApplicationApi"; -import { ResponseMeta } from "../api/ApiResponses"; +import { ApplicationResponsePayload } from "../api/ApplicationApi"; import { UpdateApplicationPayload, ImportApplicationRequest, + FetchApplicationPayload, } from "api/ApplicationApi"; +import { Datasource } from "entities/Datasource"; + +export enum ApplicationVersion { + DEFAULT = 1, + SLUG_URL = 2, +} export const setDefaultApplicationPageSuccess = ( pageId: string, @@ -24,31 +25,10 @@ export const setDefaultApplicationPageSuccess = ( }; }; -export interface FetchApplicationPayload { - applicationId: string; - mode: APP_MODE; -} - -export type FetchApplicationReduxAction = ReduxActionWithCallbacks< - FetchApplicationPayload, - FetchApplicationResponse, - string ->; - -export const fetchApplication = ({ - onErrorCallback, - onSuccessCallback, - payload, -}: { - payload: FetchApplicationPayload; - onSuccessCallback?: (payload: FetchApplicationResponse) => void; - onErrorCallback?: (error: string) => void; -}): FetchApplicationReduxAction => { +export const fetchApplication = (payload: FetchApplicationPayload) => { return { type: ReduxActionTypes.FETCH_APPLICATION_INIT, payload, - onSuccessCallback, - onErrorCallback, }; }; @@ -68,12 +48,14 @@ export const updateApplicationLayout = ( export const updateApplication = ( id: string, data: UpdateApplicationPayload, + callback?: () => void, ) => { return { type: ReduxActionTypes.UPDATE_APPLICATION, payload: { id, ...data, + callback, }, }; }; @@ -103,6 +85,15 @@ export const importApplication = (appDetails: ImportApplicationRequest) => { }; }; +export const importApplicationSuccess = ( + importedApp: ApplicationResponsePayload, +) => { + return { + type: ReduxActionTypes.IMPORT_APPLICATION_SUCCESS, + payload: importedApp, + }; +}; + export const getAllApplications = () => { return { type: ReduxActionTypes.GET_ALL_APPLICATION_INIT, @@ -120,104 +111,38 @@ export const setShowAppInviteUsersDialog = (payload: boolean) => ({ payload, }); -type ErrorPayload = string; -export type GetSSHKeyResponseData = { - docUrl: string; - publicKey?: string; -}; - -export type GenerateSSHKeyPairResponsePayload = { - responseMeta: ResponseMeta; - data: T; -}; - -export type GenerateSSHKeyPairReduxAction = ReduxActionWithCallbacks< - undefined, - GenerateSSHKeyPairResponsePayload, - ErrorPayload ->; - -export type GenerateKeyParams = { - onErrorCallback?: (payload: ErrorPayload) => void; - onSuccessCallback?: ( - payload: GenerateSSHKeyPairResponsePayload, - ) => void; - payload?: undefined; -}; - -export const generateSSHKeyPair = ({ - onErrorCallback, - onSuccessCallback, +export const initDatasourceConnectionDuringImportRequest = ( + payload: string, +) => ({ + type: ReduxActionTypes.INIT_DATASOURCE_CONNECTION_DURING_IMPORT_REQUEST, + payload, +}); + +export const initDatasourceConnectionDuringImportSuccess = () => ({ + type: ReduxActionTypes.INIT_DATASOURCE_CONNECTION_DURING_IMPORT_SUCCESS, +}); + +export const resetDatasourceConfigForImportFetchedFlag = () => ({ + type: ReduxActionTypes.RESET_DATASOURCE_CONFIG_FETCHED_FOR_IMPORT_FLAG, +}); + +export const setIsReconnectingDatasourcesModalOpen = (payload: { + isOpen: boolean; +}) => ({ + type: ReduxActionTypes.SET_IS_RECONNECTING_DATASOURCES_MODAL_OPEN, + payload, +}); + +export const setOrgIdForImport = (orgId?: string) => ({ + type: ReduxActionTypes.SET_ORG_ID_FOR_IMPORT, + payload: orgId, +}); + +export const showReconnectDatasourceModal = (payload: { + application: ApplicationResponsePayload; + unConfiguredDatasourceList: Array; + orgId: string; +}) => ({ + type: ReduxActionTypes.SHOW_RECONNECT_DATASOURCE_MODAL, payload, -}: GenerateKeyParams): GenerateSSHKeyPairReduxAction => { - return { - type: ReduxActionTypes.GENERATE_SSH_KEY_PAIR_INIT, - payload, - onErrorCallback, - onSuccessCallback, - }; -}; - -export const generateSSHKeyPairSuccess = ( - payload: GenerateSSHKeyPairResponsePayload, -) => { - return { - type: ReduxActionTypes.GENERATE_SSH_KEY_PAIR_SUCCESS, - payload, - }; -}; - -export type GetSSHKeyPairResponsePayload = { - responseMeta: ResponseMeta; - data: T; -}; - -export type GetSSHKeyPairReduxAction = ReduxActionWithCallbacks< - undefined, - GetSSHKeyPairResponsePayload, - ErrorPayload ->; - -export type GetKeyParams = { - onErrorCallback?: (payload: ErrorPayload) => void; - onSuccessCallback?: ( - payload: GetSSHKeyPairResponsePayload, - ) => void; - payload?: undefined; -}; - -export const getSSHKeyPair = ({ - onErrorCallback, - onSuccessCallback, - payload, -}: GetKeyParams): GetSSHKeyPairReduxAction => { - return { - type: ReduxActionTypes.FETCH_SSH_KEY_PAIR_INIT, - payload, - onErrorCallback, - onSuccessCallback, - }; -}; - -export const getSSHKeyPairSuccess = ( - payload: GetSSHKeyPairResponsePayload, -) => { - return { - type: ReduxActionTypes.FETCH_SSH_KEY_PAIR_SUCCESS, - payload, - }; -}; - -export const getSSHKeyPairError = (payload: { - error: string; - show: boolean; -}) => { - return { - type: ReduxActionErrorTypes.FETCH_SSH_KEY_PAIR_ERROR, - payload, - }; -}; - -export const initSSHKeyPairWithNull = () => ({ - type: ReduxActionTypes.INIT_SSH_KEY_PAIR_WITH_NULL, }); diff --git a/app/client/src/actions/datasourceActions.ts b/app/client/src/actions/datasourceActions.ts index 82bf5e388b..260def5628 100644 --- a/app/client/src/actions/datasourceActions.ts +++ b/app/client/src/actions/datasourceActions.ts @@ -139,9 +139,10 @@ export const setDatsourceEditorMode = (payload: { }; }; -export const fetchDatasources = () => { +export const fetchDatasources = (payload?: { orgId?: string }) => { return { type: ReduxActionTypes.FETCH_DATASOURCES_INIT, + payload, }; }; @@ -235,6 +236,13 @@ export const executeDatasourceQuery = ({ }; }; +export const setUnconfiguredDatasourcesDuringImport = ( + payload?: Array, +) => ({ + type: ReduxActionTypes.SET_UNCONFIGURED_DATASOURCES, + payload, +}); + export default { fetchDatasources, initDatasourcePane, diff --git a/app/client/src/actions/gitSyncActions.ts b/app/client/src/actions/gitSyncActions.ts index 179c068adf..6f8ad1918b 100644 --- a/app/client/src/actions/gitSyncActions.ts +++ b/app/client/src/actions/gitSyncActions.ts @@ -1,12 +1,13 @@ import { ReduxActionTypes } from "constants/ReduxActionConstants"; import { ConnectToGitPayload } from "api/GitSyncAPI"; -import { ReduxActionWithCallbacks } from "constants/ReduxActionConstants"; +import { + ReduxActionWithCallbacks, + ReduxActionErrorTypes, +} from "constants/ReduxActionConstants"; import { GitSyncModalTab, GitConfig, MergeStatus } from "entities/GitSync"; import { GitApplicationMetadata } from "api/ApplicationApi"; import { GitStatusData } from "reducers/uiReducers/gitSyncReducer"; -import { ReduxActionErrorTypes } from "../constants/ReduxActionConstants"; - -// test comment +import { ResponseMeta } from "../api/ApiResponses"; export const setIsGitSyncModalOpen = (payload: { isOpen: boolean; @@ -102,14 +103,6 @@ export const showCreateBranchPopup = () => ({ type: ReduxActionTypes.SHOW_CREATE_GIT_BRANCH_POPUP, }); -export const setIsImportAppViaGitModalOpen = (payload: { - isOpen: boolean; - organizationId?: string; -}) => ({ - type: ReduxActionTypes.SET_IS_IMPORT_APP_VIA_GIT_MODAL_OPEN, - payload, -}); - export const updateGlobalGitConfigInit = (payload: GitConfig) => ({ type: ReduxActionTypes.UPDATE_GLOBAL_GIT_CONFIG_INIT, payload, @@ -255,3 +248,130 @@ export const setDisconnectingGitApplication = (payload: { type: ReduxActionTypes.SET_DISCONNECTING_GIT_APPLICATION, payload, }); + +export const importAppFromGit = ({ + onErrorCallback, + onSuccessCallback, + payload, +}: ConnectToGitRequestParams): ConnectToGitReduxAction => ({ + type: ReduxActionTypes.IMPORT_APPLICATION_FROM_GIT_INIT, + payload, + onSuccessCallback, + onErrorCallback, +}); + +type ErrorPayload = string; +export type GetSSHKeyResponseData = { + docUrl: string; + publicKey?: string; +}; + +export type GenerateSSHKeyPairResponsePayload = { + responseMeta: ResponseMeta; + data: T; +}; + +export type GenerateSSHKeyPairReduxAction = ReduxActionWithCallbacks< + undefined, + GenerateSSHKeyPairResponsePayload, + ErrorPayload +>; + +export type GenerateKeyParams = { + onErrorCallback?: (payload: ErrorPayload) => void; + onSuccessCallback?: ( + payload: GenerateSSHKeyPairResponsePayload, + ) => void; + payload?: undefined; +}; + +export const generateSSHKeyPair = ({ + onErrorCallback, + onSuccessCallback, + payload, +}: GenerateKeyParams): GenerateSSHKeyPairReduxAction => { + return { + type: ReduxActionTypes.GENERATE_SSH_KEY_PAIR_INIT, + payload, + onErrorCallback, + onSuccessCallback, + }; +}; + +export const generateSSHKeyPairSuccess = ( + payload: GenerateSSHKeyPairResponsePayload, +) => { + return { + type: ReduxActionTypes.GENERATE_SSH_KEY_PAIR_SUCCESS, + payload, + }; +}; + +export type GetSSHKeyPairResponsePayload = { + responseMeta: ResponseMeta; + data: T; +}; + +export type GetSSHKeyPairReduxAction = ReduxActionWithCallbacks< + undefined, + GetSSHKeyPairResponsePayload, + ErrorPayload +>; + +export type GetKeyParams = { + onErrorCallback?: (payload: ErrorPayload) => void; + onSuccessCallback?: ( + payload: GetSSHKeyPairResponsePayload, + ) => void; + payload?: undefined; +}; + +export const getSSHKeyPair = ({ + onErrorCallback, + onSuccessCallback, + payload, +}: GetKeyParams): GetSSHKeyPairReduxAction => { + return { + type: ReduxActionTypes.FETCH_SSH_KEY_PAIR_INIT, + payload, + onErrorCallback, + onSuccessCallback, + }; +}; + +export const getSSHKeyPairSuccess = ( + payload: GetSSHKeyPairResponsePayload, +) => { + return { + type: ReduxActionTypes.FETCH_SSH_KEY_PAIR_SUCCESS, + payload, + }; +}; + +export const getSSHKeyPairError = (payload: { + error: string; + show: boolean; +}) => { + return { + type: ReduxActionErrorTypes.FETCH_SSH_KEY_PAIR_ERROR, + payload, + }; +}; + +export const initSSHKeyPairWithNull = () => ({ + type: ReduxActionTypes.INIT_SSH_KEY_PAIR_WITH_NULL, +}); + +export const importAppViaGitSuccess = () => ({ + type: ReduxActionTypes.IMPORT_APPLICATION_FROM_GIT_SUCCESS, +}); + +// todo define type +export const importAppViaGitError = (error: any) => ({ + type: ReduxActionTypes.IMPORT_APPLICATION_FROM_GIT_ERROR, + payload: error, +}); + +export const resetSSHKeys = () => ({ + type: ReduxActionTypes.RESET_SSH_KEY_PAIR, +}); diff --git a/app/client/src/actions/initActions.ts b/app/client/src/actions/initActions.ts index 9f36ce4f03..8f23fbb10b 100644 --- a/app/client/src/actions/initActions.ts +++ b/app/client/src/actions/initActions.ts @@ -1,20 +1,16 @@ -import { - ReduxActionTypes, - ReduxAction, - InitializeEditorPayload, -} from "constants/ReduxActionConstants"; +import { ReduxActionTypes, ReduxAction } from "constants/ReduxActionConstants"; + +export type InitializeEditorPayload = { + applicationId?: string; + pageId?: string; + branch?: string; +}; export const initEditor = ( - applicationId: string, - pageId: string, - branch?: string, + payload: InitializeEditorPayload, ): ReduxAction => ({ type: ReduxActionTypes.INITIALIZE_EDITOR, - payload: { - applicationId, - pageId, - branch, - }, + payload, }); export const resetEditorRequest = () => ({ diff --git a/app/client/src/actions/onboardingActions.ts b/app/client/src/actions/onboardingActions.ts index 40b069ccbf..8d96fb2e06 100644 --- a/app/client/src/actions/onboardingActions.ts +++ b/app/client/src/actions/onboardingActions.ts @@ -17,7 +17,7 @@ export const toggleInOnboardingWidgetSelection = (payload: boolean) => { }; export const firstTimeUserOnboardingInit = ( - applicationId: string, + applicationId: string | undefined, pageId: string, ) => { return { diff --git a/app/client/src/actions/pageActions.tsx b/app/client/src/actions/pageActions.tsx index b554ab8b03..ee2f07b4a7 100644 --- a/app/client/src/actions/pageActions.tsx +++ b/app/client/src/actions/pageActions.tsx @@ -38,23 +38,6 @@ export interface CreatePageActionPayload { blockNavigation?: boolean; } -export const fetchPageList = ( - { - applicationId, - }: { - applicationId: string; - }, - mode: APP_MODE, -): ReduxAction => { - return { - type: ReduxActionTypes.FETCH_PAGE_LIST_INIT, - payload: { - applicationId, - mode, - }, - }; -}; - export const fetchPage = ( pageId: string, isFirstLoad = false, @@ -94,9 +77,9 @@ export const fetchPublishedPageSuccess = ( payload: undefined, }); -export const updateCurrentPage = (id: string) => ({ +export const updateCurrentPage = (id: string, slug?: string) => ({ type: ReduxActionTypes.SWITCH_CURRENT_PAGE_ID, - payload: { id }, + payload: { id, slug }, }); export const initCanvasLayout = ( diff --git a/app/client/src/actions/pluginActions.ts b/app/client/src/actions/pluginActions.ts index a982b3a631..b4a3439050 100644 --- a/app/client/src/actions/pluginActions.ts +++ b/app/client/src/actions/pluginActions.ts @@ -7,8 +7,11 @@ import { import { PluginFormPayload } from "api/PluginApi"; import { DependencyMap } from "utils/DynamicBindingUtils"; -export const fetchPlugins = (): ReduxActionWithoutPayload => ({ +export const fetchPlugins = (payload?: { + orgId?: string; +}): ReduxAction<{ orgId?: string } | undefined> => ({ type: ReduxActionTypes.FETCH_PLUGINS_REQUEST, + payload, }); export const fetchPluginFormConfigs = (): ReduxActionWithoutPayload => ({ diff --git a/app/client/src/api/ApiResponses.tsx b/app/client/src/api/ApiResponses.tsx index 5935f5913b..2184ee33b3 100644 --- a/app/client/src/api/ApiResponses.tsx +++ b/app/client/src/api/ApiResponses.tsx @@ -9,9 +9,9 @@ export type ResponseMeta = { error?: APIResponseError; }; -export type ApiResponse = { +export type ApiResponse = { responseMeta: ResponseMeta; - data: any; + data: T; code?: string; }; diff --git a/app/client/src/api/ApplicationApi.tsx b/app/client/src/api/ApplicationApi.tsx index d94d18bbd4..4d99bd1f61 100644 --- a/app/client/src/api/ApplicationApi.tsx +++ b/app/client/src/api/ApplicationApi.tsx @@ -4,6 +4,9 @@ import { AxiosPromise } from "axios"; import { AppColorCode } from "constants/DefaultTheme"; import { AppIconName } from "components/ads/AppIcon"; import { AppLayoutConfig } from "reducers/entityReducers/pageListReducer"; +import { APP_MODE } from "entities/App"; +import { ApplicationVersion } from "actions/applicationActions"; +import { Datasource } from "entities/Datasource"; export type EvaluationVersion = number; @@ -16,14 +19,14 @@ export interface ChangeAppViewAccessRequest { publicAccess: boolean; } -export interface PublishApplicationResponse extends ApiResponse { - data: unknown; -} +export type PublishApplicationResponse = ApiResponse; export interface ApplicationPagePayload { id: string; name: string; isDefault: boolean; + slug?: string; + isHidden?: boolean; } export type GitApplicationMetadata = @@ -44,25 +47,36 @@ export interface ApplicationResponsePayload { name: string; organizationId: string; evaluationVersion?: EvaluationVersion; - pages?: ApplicationPagePayload[]; + pages: ApplicationPagePayload[]; appIsExample: boolean; appLayout?: AppLayoutConfig; unreadCommentThreads?: number; gitApplicationMetadata: GitApplicationMetadata; + slug: string; + applicationVersion: ApplicationVersion; } -export interface FetchApplicationResponse extends ApiResponse { - data: ApplicationResponsePayload & { pages: ApplicationPagePayload[] }; +export interface FetchApplicationPayload { + applicationId?: string; + pageId?: string; + mode: APP_MODE; } -export interface FetchApplicationsResponse extends ApiResponse { - data: Array; +export interface FetchApplicationResponseData { + application: Omit; + pages: ApplicationPagePayload[]; + organizationId: string; } -export interface CreateApplicationResponse extends ApiResponse { - data: ApplicationResponsePayload; -} +export type FetchApplicationResponse = ApiResponse< + FetchApplicationResponseData +>; +export type FetchApplicationsResponse = ApiResponse< + FetchApplicationResponseData[] +>; + +export type CreateApplicationResponse = ApiResponse; export interface CreateApplicationRequest { name: string; orgId: string; @@ -87,9 +101,7 @@ export interface ForkApplicationRequest { organizationId: string; } -export interface GetAllApplicationResponse extends ApiResponse { - data: Array; -} +export type GetAllApplicationResponse = ApiResponse; export type UpdateApplicationPayload = { icon?: string; @@ -97,10 +109,12 @@ export type UpdateApplicationPayload = { name?: string; currentApp?: boolean; appLayout?: AppLayoutConfig; + applicationVersion?: number; }; export type UpdateApplicationRequest = UpdateApplicationPayload & { id: string; + callback?: () => void; }; export interface ApplicationObject { @@ -136,6 +150,10 @@ export interface FetchUsersApplicationsOrgsResponse extends ApiResponse { }; } +export interface FetchUnconfiguredDatasourceListResponse extends ApiResponse { + data: Array; +} + export interface ImportApplicationRequest { orgId: string; applicationFile?: File; @@ -176,6 +194,15 @@ class ApplicationApi extends Api { return Api.get(ApplicationApi.baseURL + "/" + applicationId); } + static fetchUnconfiguredDatasourceList(payload: { + applicationId: string; + orgId: string; + }): AxiosPromise { + return Api.get( + `${ApplicationApi.baseURL}/import/${payload.orgId}/datasources?defaultApplicationId=${payload.applicationId}`, + ); + } + static fetchApplicationForViewMode( applicationId: string, ): AxiosPromise { @@ -258,14 +285,6 @@ class ApplicationApi extends Api { }, ); } - - static getSSHKeyPair(applicationId: string): AxiosPromise { - return Api.get(ApplicationApi.baseURL + "/ssh-keypair/" + applicationId); - } - - static generateSSHKeyPair(applicationId: string): AxiosPromise { - return Api.post(ApplicationApi.baseURL + "/ssh-keypair/" + applicationId); - } } export default ApplicationApi; diff --git a/app/client/src/api/GitSyncAPI.tsx b/app/client/src/api/GitSyncAPI.tsx index f861748517..a69ede8699 100644 --- a/app/client/src/api/GitSyncAPI.tsx +++ b/app/client/src/api/GitSyncAPI.tsx @@ -2,6 +2,7 @@ import { AxiosPromise } from "axios"; import Api from "api/Api"; import { ApiResponse } from "./ApiResponses"; import { GitConfig } from "entities/GitSync"; +import ApplicationApi from "./ApplicationApi"; export type CommitPayload = { applicationId: string; @@ -28,7 +29,6 @@ export type ConnectToGitPayload = { authorName: string; authorEmail: string; }; - isImport?: boolean; isDefaultProfile?: boolean; }; @@ -131,6 +131,24 @@ class GitSyncAPI extends Api { static disconnectGit({ applicationId }: { applicationId: string }) { return Api.post(`${GitSyncAPI.baseURL}/disconnect/${applicationId}`); } + + static importApp(payload: ConnectToGitPayload, orgId: string) { + return Api.post(`${GitSyncAPI.baseURL}/import/${orgId}`, payload); + } + + static getSSHKeyPair(applicationId: string): AxiosPromise { + return Api.get(ApplicationApi.baseURL + "/ssh-keypair/" + applicationId); + } + + static generateSSHKeyPair( + applicationId: string, + isImporting?: boolean, + ): AxiosPromise { + const url = isImporting + ? "v1/git/import/keys" + : ApplicationApi.baseURL + "/ssh-keypair/" + applicationId; + return isImporting ? Api.get(url) : Api.post(url); + } } export default GitSyncAPI; diff --git a/app/client/src/api/OAuthApi.ts b/app/client/src/api/OAuthApi.ts index a0e827486b..e5891efc92 100644 --- a/app/client/src/api/OAuthApi.ts +++ b/app/client/src/api/OAuthApi.ts @@ -10,8 +10,12 @@ class OAuthApi extends Api { static getAppsmithToken( datasourceId: string, pageId: string, + isImport?: boolean, ): AxiosPromise> { - return Api.post(`${OAuthApi.url}/${datasourceId}/pages/${pageId}/oauth`); + const isImportQuery = isImport ? "?importForGit=true" : ""; + return Api.post( + `${OAuthApi.url}/${datasourceId}/pages/${pageId}/oauth${isImportQuery}`, + ); } // Api endpoint to get access token for datasource authorization diff --git a/app/client/src/api/PageApi.tsx b/app/client/src/api/PageApi.tsx index 0194d3e6b6..0a3040d0ce 100644 --- a/app/client/src/api/PageApi.tsx +++ b/app/client/src/api/PageApi.tsx @@ -7,95 +7,86 @@ import { ClonePageActionPayload, CreatePageActionPayload, } from "actions/pageActions"; +import { FetchApplicationResponse } from "./ApplicationApi"; -export interface FetchPageRequest { +export type FetchPageRequest = { id: string; isFirstLoad?: boolean; -} + handleResponseLater?: boolean; +}; -export interface FetchPublishedPageRequest { +export type FetchPublishedPageRequest = { pageId: string; bustCache?: boolean; -} +}; -export interface SavePageRequest { +export type SavePageRequest = { dsl: DSLWidget; layoutId: string; pageId: string; -} +}; -export interface PageLayout { +export type PageLayout = { id: string; dsl: Partial; layoutOnLoadActions: PageAction[][]; layoutActions: PageAction[]; -} +}; -export type FetchPageResponse = ApiResponse & { - data: { +export type FetchPageResponseData = { + id: string; + name: string; + slug: string; + applicationId: string; + layouts: Array; + lastUpdatedTime: number; +}; + +export type FetchPublishedPageResponseData = FetchPageResponseData; + +export type SavePageResponseData = { + id: string; + layoutOnLoadActions: PageAction[][]; + dsl: Partial; + messages: string[]; + actionUpdates: Array<{ + executeOnLoad: boolean; id: string; name: string; - applicationId: string; - layouts: Array; - }; + collectionId?: string; + }>; }; -export type FetchPublishedPageResponse = ApiResponse & { - data: { - id: string; - dsl: Partial; - pageId: string; - }; -}; - -export interface SavePageResponse extends ApiResponse { - data: { - id: string; - layoutOnLoadActions: PageAction[][]; - dsl: Partial; - messages: string[]; - actionUpdates: Array<{ - executeOnLoad: boolean; - id: string; - name: string; - collectionId?: string; - }>; - }; -} - export type CreatePageRequest = Omit< CreatePageActionPayload, "blockNavigation" >; -export interface UpdatePageRequest { +export type UpdatePageRequest = { id: string; name: string; isHidden?: boolean; -} +}; -export interface SetPageOrderRequest { +export type SetPageOrderRequest = { order: number; pageId: string; applicationId: string; -} +}; -export interface CreatePageResponse extends ApiResponse { - data: unknown; -} +export type CreatePageResponse = ApiResponse; -export interface FetchPageListResponse extends ApiResponse { - data: { - pages: Array<{ - id: string; - name: string; - isDefault: boolean; - isHidden?: boolean; - layouts: Array; - }>; - organizationId: string; - }; -} +export type FetchPageListResponseData = { + pages: Array<{ + id: string; + name: string; + isDefault: boolean; + isHidden?: boolean; + layouts: Array; + slug?: string; + }>; + organizationId: string; +}; export interface DeletePageRequest { id: string; @@ -110,10 +101,6 @@ export interface UpdateWidgetNameRequest { oldName: string; } -export interface UpdateWidgetNameResponse extends ApiResponse { - data: PageLayout; -} - export interface GenerateTemplatePageRequest { pageId: string; tableName: string; @@ -125,15 +112,29 @@ export interface GenerateTemplatePageRequest { pluginSpecificParams?: Record; } -export type GenerateTemplatePageRequestResponse = ApiResponse & { - data: { - id: string; - name: string; - applicationId: string; - layouts: Array; - }; +export type GenerateTemplatePageResponseData = { + id: string; + name: string; + applicationId: string; + layouts: Array; }; +export type SavePageResponse = ApiResponse; + +export type FetchPageListResponse = ApiResponse; + +export type UpdateWidgetNameResponse = ApiResponse; + +export type GenerateTemplatePageRequestResponse = ApiResponse< + GenerateTemplatePageResponseData +>; + +export type FetchPageResponse = ApiResponse; + +export type FetchPublishedPageResponse = ApiResponse< + FetchPublishedPageResponseData +>; + class PageApi extends Api { static url = "v1/pages"; static refactorLayoutURL = "v1/layouts/refactor"; @@ -248,6 +249,10 @@ class PageApi extends Api { ), ); } + + static fetchAppAndPages(params: any): AxiosPromise { + return Api.get(PageApi.url, params); + } } export default PageApi; diff --git a/app/client/src/api/TemplatesApi.ts b/app/client/src/api/TemplatesApi.ts index bb4eca1a37..4736821bd1 100644 --- a/app/client/src/api/TemplatesApi.ts +++ b/app/client/src/api/TemplatesApi.ts @@ -51,7 +51,7 @@ class TemplatesAPI extends Api { static importTemplate( templateId: string, organizationId: string, - ): AxiosPromise { + ): AxiosPromise { return Api.post( TemplatesAPI.baseUrl + `/app-templates/${templateId}/import/${organizationId}`, diff --git a/app/client/src/assets/icons/widget/json-form.svg b/app/client/src/assets/icons/widget/json-form.svg new file mode 100644 index 0000000000..885be38088 --- /dev/null +++ b/app/client/src/assets/icons/widget/json-form.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/app/client/src/ce/constants/messages.test.ts b/app/client/src/ce/constants/messages.test.ts index f8b3407bf0..0e41c0f60e 100644 --- a/app/client/src/ce/constants/messages.test.ts +++ b/app/client/src/ce/constants/messages.test.ts @@ -175,7 +175,7 @@ describe("git-sync messages", () => { }, { key: "NONE_REVERSIBLE_MESSAGE", - value: "This action is non reversible. Proceed with caution", + value: "This action is non reversible. Proceed with caution.", }, { key: "CONTACT_SUPPORT_TO_UPGRADE", @@ -186,7 +186,7 @@ describe("git-sync messages", () => { key: "DISCONNECT_CAUSE_APPLICATION_BREAK", value: "Disconnect might cause the application to break.", }, - { key: "DISCONNECT_GIT", value: "Disconnect git" }, + { key: "DISCONNECT_GIT", value: "Revoke access" }, { key: "DISCONNECT", value: "DISCONNECT" }, { key: "GIT_DISCONNECTION_SUBMENU", value: "Git Connection > Disconnect" }, { key: "USE_DEFAULT_CONFIGURATION", value: "Use default configuration" }, diff --git a/app/client/src/ce/constants/messages.ts b/app/client/src/ce/constants/messages.ts index c9cf1e4f4c..5183bfd986 100644 --- a/app/client/src/ce/constants/messages.ts +++ b/app/client/src/ce/constants/messages.ts @@ -97,8 +97,8 @@ export const FORGOT_PASSWORD_PAGE_TITLE = () => `Reset password`; export const FORGOT_PASSWORD_PAGE_SUBTITLE = () => `We will send a reset link to the email below`; export const FORGOT_PASSWORD_PAGE_SUBMIT_BUTTON_TEXT = () => `Reset`; -export const FORGOT_PASSWORD_SUCCESS_TEXT = () => - `A password reset link has been sent to`; +export const FORGOT_PASSWORD_SUCCESS_TEXT = (email: string) => + `A password reset link has been sent to your email address ${email} registered with Appsmith.`; export const PRIVACY_POLICY_LINK = () => `Privacy policy`; export const TERMS_AND_CONDITIONS_LINK = () => `Terms and conditions`; @@ -462,6 +462,33 @@ export const JS_SETTINGS_EXECUTE_TIMEOUT = () => // Import/Export Application features export const IMPORT_APPLICATION_MODAL_TITLE = () => "Import application"; +export const IMPORT_APPLICATION_MODAL_LABEL = () => + "Where would you like to import your application from?"; +export const IMPORT_APP_FROM_FILE_TITLE = () => "Import from file"; +export const IMPORT_APP_FROM_GIT_TITLE = () => "Import from a Git repo (Beta)"; +export const IMPORT_APP_FROM_FILE_MESSAGE = () => + "Drag and drop your file or upload from your computer"; +export const IMPORT_APP_FROM_GIT_MESSAGE = () => + "Import an application from its git repository using its SSH URL"; +export const IMPORT_FROM_GIT_REPOSITORY = () => "Import from Git Repository"; +export const IMPORT_FROM_GIT_REPOSITORY_MESSAGE = () => + "While importing Appsmith will does not import the datasource credentials to prevent a breach. After a successfull import you can add the credentials manually so the application behaves normally!"; +export const RECONNECT_MISSING_DATASOURCE_CREDENTIALS = () => + "Reconnect missing datasource credentials"; +export const RECONNECT_MISSING_DATASOURCE_CREDENTIALS_DESCRIPTION = () => + "Fill these with utmost care as the application will not behave normally otherwsie"; +export const RECONNECT_DATASOURCE_SUCCESS_MESSAGE1 = () => + "These datasources were imported successfully!"; +export const RECONNECT_DATASOURCE_SUCCESS_MESSAGE2 = () => + "Please fill up the missing datasources"; +export const ADD_MISSING_DATASOURCES = () => "Add missing Datasources"; +export const SKIP_TO_APPLICATION_TOOLTIP_HEADER = () => + "This action is irreversible."; +export const SKIP_TO_APPLICATION_TOOLTIP_DESCRIPTION = () => + `You can always reconnect the datasources later but until then the application might be unuseable.`; +export const SKIP_TO_APPLICATION = () => "Skip to Application"; +export const SELECT_A_METHOD_TO_ADD_CREDENTIALS = () => + "Select a method to add credentials"; export const DELETE_CONFIRMATION_MODAL_TITLE = () => `Are you sure?`; export const DELETE_CONFIRMATION_MODAL_SUBTITLE = (name?: string | null) => `You want to remove ${name} from this organization`; @@ -561,6 +588,7 @@ export const GIT_DISCONNECT_POPUP_SUBTITLE = () => export const GIT_DISCONNECT_POPUP_MAIN_HEADING = () => `Are you sure ?`; export const GIT_CONNECTION = () => "Git Connection"; +export const GIT_IMPORT = () => "Git Import"; export const DEPLOY = () => "Deploy"; export const MERGE = () => "Merge"; export const GIT_SETTINGS = () => "Git Settings"; @@ -629,6 +657,7 @@ export const PASTE_SSH_URL_INFO = () => export const GENERATE_KEY = () => "Generate Key"; export const UPDATE_CONFIG = () => "UPDATE CONFIG"; export const CONNECT_BTN_LABEL = () => "CONNECT"; +export const IMPORT_BTN_LABEL = () => "IMPORT"; export const FETCH_GIT_STATUS = () => "fetching status..."; export const FETCH_MERGE_STATUS = () => "Checking mergeability..."; export const NO_MERGE_CONFLICT = () => @@ -648,6 +677,9 @@ export const DISCONNECT_SERVICE_SUBHEADER = () => "Changes to this section can disrupt user authentication. Proceed with caution."; export const DISCONNECT_SERVICE_WARNING = () => "will be removed as primary method of authentication"; +export const AUTHENTICATION_METHOD_ENABLED = (methodName: string) => ` + ${methodName} authentication method is enabled +`; export const DISCONNECT_EXISTING_REPOSITORIES = () => "Disconnect existing Repositories"; @@ -660,22 +692,26 @@ export const REPOSITORY_LIMIT_REACHED = () => "Repository Limit Reached"; export const REPOSITORY_LIMIT_REACHED_INFO = () => "Adding and using upto 3 repositories is free. To add more repositories kindly upgrade."; export const NONE_REVERSIBLE_MESSAGE = () => - "This action is non reversible. Proceed with caution"; + "This action is non reversible. Proceed with caution."; export const CONTACT_SUPPORT_TO_UPGRADE = () => "Contact support to upgrade. You can add unlimited private repositories in upgraded plan."; export const DISCONNECT_CAUSE_APPLICATION_BREAK = () => "Disconnect might cause the application to break."; -export const DISCONNECT_GIT = () => "Disconnect git"; +export const DISCONNECT_GIT = () => "Revoke access"; export const DISCONNECT = () => "DISCONNECT"; +export const REVOKE = () => "REVOKE"; +export const REVOKE_ACCESS = () => "REVOKE ACCESS"; export const GIT_DISCONNECTION_SUBMENU = () => "Git Connection > Disconnect"; export const DISCONNECT_FROM_GIT = (name: string) => `Disconnect ${name} from Git`; -export const TYPE_PROMO_CODE = (name: string) => - `Type “${name}” in the input box to disconnect.`; -export const APPLICATION_NAME = () => "Application Name"; +export const GIT_REVOKE_ACCESS = (name: string) => `Revoke Access To ${name}`; +export const GIT_TYPE_REPO_NAME_FOR_REVOKING_ACCESS = (name: string) => + `Type “${name}” in the input box to revoke access.`; +export const APPLICATION_NAME = () => "Application name"; export const NOT_OPTIONS = () => "Not Options!"; export const OPEN_REPO = () => "OPEN REPO"; export const CONNECTING_REPO = () => "CONNECTING TO GIT REPO"; +export const IMPORTING_APP_FROM_GIT = () => "IMPORTING APPLICATION FROM GIT"; export const ERROR_CONNECTING = () => "Error while connecting"; export const ERROR_COMMITTING = () => "Error while committing"; export const CONFIRM_SSH_KEY = () => "Make sure your SSH Key has write access."; @@ -946,7 +982,7 @@ export const WELCOME_FORM_NON_SUPER_USER_ROLE = () => "Role"; export const WELCOME_FORM_NON_SUPER_USER_USE_CASE = () => "What are you planning to use Appsmith for?"; export const QUERY_CONFIRMATION_MODAL_MESSAGE = () => - "Are you sure you want to perform this action?"; + `Are you sure you want to run `; export const ENTITY_EXPLORER_TITLE = () => "NAVIGATION"; export const MULTI_SELECT_PROPERTY_PANE_MESSAGE = () => `Select a widget to see it's properties`; @@ -961,11 +997,6 @@ export const TABLE_WIDGET_TOTAL_RECORD_TOOLTIP = () => export const CREATE_DATASOURCE_TOOLTIP = () => "Add a new datasource"; export const ADD_QUERY_JS_TOOLTIP = () => "Create New"; -// Add datasource -export const GENERATE_APPLICATION_TITLE = () => "Generate Page"; -export const GENERATE_APPLICATION_DESCRIPTION = () => - "Quickly generate a page to perform CRUD operations on your database tables"; - export const DELETE_ORG_SUCCESSFUL = () => "Organization deleted successfully"; export const UPGRADE_TO_EE = (authLabel: string) => @@ -974,6 +1005,8 @@ export const ADMIN_AUTH_SETTINGS_TITLE = () => "Select Authentication Method"; export const ADMIN_AUTH_SETTINGS_SUBTITLE = () => "Select a protocol you want to authenticate users with"; export const DANGER_ZONE = () => "Danger Zone"; +export const DISCONNECT_AUTH_METHOD = () => "Disconnect"; +export const DISCONNECT_CONFIRMATION = () => "Are you sure?"; // Guided tour // -- STEPS --- @@ -1047,7 +1080,11 @@ export const CONTEXT_SHOW_BINDING = () => "Show Bindings"; export const CONTEXT_MOVE = () => "Move to page"; export const CONTEXT_COPY = () => "Copy to page"; export const CONTEXT_DELETE = () => "Delete"; +export const CONFIRM_CONTEXT_DELETE = () => "Are you sure?"; export const CONTEXT_NO_PAGE = () => "No pages"; +export const CONTEXT_REFRESH = () => "Refresh"; +export const CONTEXT_CLONE = () => "Clone"; +export const CONTEXT_SET_AS_HOME_PAGE = () => "Set as Home Page"; // Entity explorer export const ADD_DATASOURCE_BUTTON = () => "ADD DATASOURCE"; @@ -1099,3 +1136,9 @@ export const FORK_APP_MODAL_EMPTY_TITLE = () => export const FORK_APP_MODAL_SUCCESS_TITLE = () => "Choose where to fork the app"; export const FORK = () => `FORK`; + +export const CLEAN_URL_UPDATE = { + name: () => "Update URLs", + shortDesc: () => + "All URLs in your applications will update to a new readable format that includes the application and page names.", +}; diff --git a/app/client/src/ce/pages/AdminSettings/BreadcrumbCategories.tsx b/app/client/src/ce/pages/AdminSettings/BreadcrumbCategories.tsx index fcb2d3b17c..03bfb34def 100644 --- a/app/client/src/ce/pages/AdminSettings/BreadcrumbCategories.tsx +++ b/app/client/src/ce/pages/AdminSettings/BreadcrumbCategories.tsx @@ -1,8 +1,6 @@ -import { - APPLICATIONS_URL, - getAdminSettingsCategoryUrl, -} from "constants/routes"; +import { APPLICATIONS_URL } from "constants/routes"; import { SettingCategories } from "@appsmith/pages/AdminSettings/config/types"; +import { adminSettingsCategoryUrl } from "RouteBuilder"; export const BreadcrumbCategories = { HOMEPAGE: { @@ -10,48 +8,50 @@ export const BreadcrumbCategories = { text: "Homepage", }, [SettingCategories.GENERAL]: { - href: getAdminSettingsCategoryUrl(SettingCategories.GENERAL), + href: adminSettingsCategoryUrl({ category: SettingCategories.GENERAL }), text: "General", }, [SettingCategories.EMAIL]: { - href: getAdminSettingsCategoryUrl(SettingCategories.EMAIL), + href: adminSettingsCategoryUrl({ category: SettingCategories.EMAIL }), text: "Email", }, [SettingCategories.GOOGLE_MAPS]: { - href: getAdminSettingsCategoryUrl(SettingCategories.GOOGLE_MAPS), + href: adminSettingsCategoryUrl({ category: SettingCategories.GOOGLE_MAPS }), text: "Google Maps", }, [SettingCategories.VERSION]: { - href: getAdminSettingsCategoryUrl(SettingCategories.VERSION), + href: adminSettingsCategoryUrl({ category: SettingCategories.VERSION }), text: "Version", }, [SettingCategories.ADVANCED]: { - href: getAdminSettingsCategoryUrl(SettingCategories.ADVANCED), + href: adminSettingsCategoryUrl({ category: SettingCategories.ADVANCED }), text: "Advanced", }, [SettingCategories.AUTHENTICATION]: { - href: getAdminSettingsCategoryUrl(SettingCategories.AUTHENTICATION), + href: adminSettingsCategoryUrl({ + category: SettingCategories.AUTHENTICATION, + }), text: "Authentication", }, [SettingCategories.FORM_AUTH]: { - href: getAdminSettingsCategoryUrl( - SettingCategories.AUTHENTICATION, - SettingCategories.FORM_AUTH, - ), + href: adminSettingsCategoryUrl({ + category: SettingCategories.AUTHENTICATION, + subCategory: SettingCategories.FORM_AUTH, + }), text: "Form Login", }, [SettingCategories.GOOGLE_AUTH]: { - href: getAdminSettingsCategoryUrl( - SettingCategories.AUTHENTICATION, - SettingCategories.GOOGLE_AUTH, - ), + href: adminSettingsCategoryUrl({ + category: SettingCategories.AUTHENTICATION, + subCategory: SettingCategories.GOOGLE_AUTH, + }), text: "Google Authentication", }, [SettingCategories.GITHUB_AUTH]: { - href: getAdminSettingsCategoryUrl( - SettingCategories.AUTHENTICATION, - SettingCategories.GITHUB_AUTH, - ), + href: adminSettingsCategoryUrl({ + category: SettingCategories.AUTHENTICATION, + subCategory: SettingCategories.GITHUB_AUTH, + }), text: "Github Authentication", }, }; diff --git a/app/client/src/ce/pages/AdminSettings/config/authentication/AuthPage.tsx b/app/client/src/ce/pages/AdminSettings/config/authentication/AuthPage.tsx index fb9e5a166c..c0fa1e9b27 100644 --- a/app/client/src/ce/pages/AdminSettings/config/authentication/AuthPage.tsx +++ b/app/client/src/ce/pages/AdminSettings/config/authentication/AuthPage.tsx @@ -11,8 +11,8 @@ import { EDIT, UPGRADE, UPGRADE_TO_EE, + AUTHENTICATION_METHOD_ENABLED, } from "@appsmith/constants/messages"; -import { getAdminSettingsCategoryUrl } from "constants/routes"; import { Callout, CalloutType } from "components/ads/CalloutV2"; import { getAppsmithConfigs } from "@appsmith/configs"; import { getCurrentUser } from "selectors/usersSelectors"; @@ -20,6 +20,9 @@ import { useSelector } from "react-redux"; import bootIntercom from "utils/bootIntercom"; import { Colors } from "constants/Colors"; import Icon from "components/ads/Icon"; +import TooltipComponent from "components/ads/Tooltip"; +import { Position } from "@blueprintjs/core"; +import { adminSettingsCategoryUrl } from "RouteBuilder"; const { intercomAppID } = getAppsmithConfigs(); @@ -122,7 +125,7 @@ const Label = styled.span<{ enterprise?: boolean }>` background: #fff; ` : ` - color: #03B365; + color: ${Colors.GREEN}; background: #E5F6EC; `}; padding: 0px 4px; @@ -170,7 +173,19 @@ export function AuthPage({ authMethods }: { authMethods: AuthMethodType[] }) { )} {method.isConnected && ( - + + + )} {method.subText} @@ -193,10 +208,10 @@ export function AuthPage({ authMethods }: { authMethods: AuthMethodType[] }) { onClick={() => !method.needsUpgrade || method.isConnected ? history.push( - getAdminSettingsCategoryUrl( - SettingCategories.AUTHENTICATION, - method.category, - ), + adminSettingsCategoryUrl({ + category: SettingCategories.AUTHENTICATION, + subCategory: method.category, + }), ) : triggerIntercom(method.label) } diff --git a/app/client/src/ce/pages/UserAuth/SignUp.tsx b/app/client/src/ce/pages/UserAuth/SignUp.tsx index 2b719cd8f6..dc5bd5efd6 100644 --- a/app/client/src/ce/pages/UserAuth/SignUp.tsx +++ b/app/client/src/ce/pages/UserAuth/SignUp.tsx @@ -94,6 +94,7 @@ export function SignUp(props: SignUpFormProps) { const { emailValue: email, error, pristine, submitting, valid } = props; const isFormValid = valid && email && !isEmptyString(email); const socialLoginList = ThirdPartyLoginRegistry.get(); + const shouldDisableSignupButton = pristine || !isFormValid; const location = useLocation(); const recaptchaStatus = useScript( @@ -119,6 +120,32 @@ export function SignUp(props: SignUpFormProps) { } } + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault(); + const formElement: HTMLFormElement = document.getElementById( + "signup-form", + ) as HTMLFormElement; + if ( + googleRecaptchaSiteKey.enabled && + recaptchaStatus === ScriptStatus.READY + ) { + window.grecaptcha + .execute(googleRecaptchaSiteKey.apiKey, { + action: "submit", + }) + .then(function(token: any) { + formElement && + formElement.setAttribute( + "action", + `${signupURL}?recaptchaToken=${token}`, + ); + formElement && formElement.submit(); + }); + } else { + formElement && formElement.submit(); + } + }; + return ( <> {showError && } @@ -137,78 +164,57 @@ export function SignUp(props: SignUpFormProps) { {socialLoginList.length > 0 && ( )} - { - e.preventDefault(); - const formElement: HTMLFormElement = document.getElementById( - "signup-form", - ) as HTMLFormElement; - if ( - googleRecaptchaSiteKey.enabled && - recaptchaStatus === ScriptStatus.READY - ) { - window.grecaptcha - .execute(googleRecaptchaSiteKey.apiKey, { - action: "submit", - }) - .then(function(token: any) { - formElement && - formElement.setAttribute( - "action", - `${signupURL}?recaptchaToken=${token}`, - ); - formElement && formElement.submit(); - }); - } else { - formElement && formElement.submit(); - } - return false; - }} - > - handleSubmit(e)} > - - - - - - -