Browse Source

Merge pull request #3597 from nocodb/chore/cypress-improvements

chore(cypress): improvements
pull/3624/head
Raju Udava 2 years ago committed by GitHub
parent
commit
98b24ed06a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      packages/nc-gui/components/cell/DatePicker.vue
  2. 2
      packages/nc-gui/components/cell/DateTimePicker.vue
  3. 2
      packages/nc-gui/components/cell/TimePicker.vue
  4. 2
      packages/nc-gui/components/cell/YearPicker.vue
  5. 8
      packages/nc-gui/components/cell/attachment/Modal.vue
  6. 4
      packages/nc-gui/components/dashboard/TreeView.vue
  7. 18
      packages/nc-gui/components/dashboard/settings/AppStore.vue
  8. 1
      packages/nc-gui/components/dashboard/settings/Modal.vue
  9. 8
      packages/nc-gui/components/dlg/AirtableImport.vue
  10. 8
      packages/nc-gui/components/dlg/QuickImport.vue
  11. 8
      packages/nc-gui/components/dlg/TableCreate.vue
  12. 1
      packages/nc-gui/components/dlg/TableRename.vue
  13. 2
      packages/nc-gui/components/dlg/ViewCreate.vue
  14. 2
      packages/nc-gui/components/dlg/ViewDelete.vue
  15. 2
      packages/nc-gui/components/general/HelpAndSupport.vue
  16. 4
      packages/nc-gui/components/general/MiniSidebar.vue
  17. 2
      packages/nc-gui/components/general/ReleaseInfo.vue
  18. 6
      packages/nc-gui/components/general/language/index.vue
  19. 1
      packages/nc-gui/components/shared-view/AskPassword.vue
  20. 6
      packages/nc-gui/components/smartsheet-column/SelectOptions.vue
  21. 8
      packages/nc-gui/components/smartsheet-header/Cell.vue
  22. 2
      packages/nc-gui/components/smartsheet-header/Menu.vue
  23. 8
      packages/nc-gui/components/smartsheet-header/VirtualCell.vue
  24. 3
      packages/nc-gui/components/smartsheet-toolbar/ColumnFilter.vue
  25. 2
      packages/nc-gui/components/smartsheet-toolbar/ColumnFilterMenu.vue
  26. 2
      packages/nc-gui/components/smartsheet-toolbar/Export.vue
  27. 2
      packages/nc-gui/components/smartsheet-toolbar/FieldsMenu.vue
  28. 8
      packages/nc-gui/components/smartsheet-toolbar/MoreActions.vue
  29. 1
      packages/nc-gui/components/smartsheet-toolbar/ShareView.vue
  30. 2
      packages/nc-gui/components/smartsheet-toolbar/SortListMenu.vue
  31. 10
      packages/nc-gui/components/smartsheet-toolbar/ViewActions.vue
  32. 2
      packages/nc-gui/components/smartsheet/ApiSnippet.vue
  33. 2
      packages/nc-gui/components/smartsheet/Form.vue
  34. 12
      packages/nc-gui/components/smartsheet/Grid.vue
  35. 1
      packages/nc-gui/components/smartsheet/expanded-form/index.vue
  36. 2
      packages/nc-gui/components/smartsheet/sidebar/toolbar/DebugMeta.vue
  37. 20
      packages/nc-gui/components/tabs/auth/ApiTokenManagement.vue
  38. 11
      packages/nc-gui/components/tabs/auth/UserManagement.vue
  39. 2
      packages/nc-gui/components/tabs/auth/user-management/ShareBase.vue
  40. 10
      packages/nc-gui/components/tabs/auth/user-management/UsersModal.vue
  41. 9
      packages/nc-gui/components/virtual-cell/components/ListChildItems.vue
  42. 8
      packages/nc-gui/components/virtual-cell/components/ListItems.vue
  43. 1
      packages/nc-gui/components/webhook/Drawer.vue
  44. 1
      packages/nc-gui/composables/useTable.ts
  45. 2
      packages/nc-gui/layouts/base.vue
  46. 4
      packages/nc-gui/lib/enums.ts
  47. 7
      packages/nc-gui/pages/[projectType]/[projectId]/index.vue
  48. 1
      packages/nc-gui/pages/[projectType]/form/[viewId]/index.vue
  49. 9
      packages/nc-gui/pages/index/index/create-external.vue
  50. 3
      packages/nc-gui/pages/index/index/index.vue
  51. 2
      packages/nc-gui/pages/projects/index/index.vue
  52. 147
      scripts/cypress/integration/common/00_pre_configurations.js
  53. 6
      scripts/cypress/integration/common/1b_table_column_operations.js
  54. 2
      scripts/cypress/integration/common/1d_pg_table_view_drag_drop_reorder.js
  55. 2
      scripts/cypress/integration/common/1d_table_view_drag_drop_reorder.js
  56. 12
      scripts/cypress/integration/common/2a_table_with_belongs_to_colulmn.js
  57. 16
      scripts/cypress/integration/common/2b_table_with_m2m_column.js
  58. 8
      scripts/cypress/integration/common/3a_filter_sort_fields_operations.js
  59. 15
      scripts/cypress/integration/common/3b_formula_column.js
  60. 4
      scripts/cypress/integration/common/3c_lookup_column.js
  61. 2
      scripts/cypress/integration/common/3d_rollup_column.js
  62. 5
      scripts/cypress/integration/common/3e_duration_column.js
  63. 20
      scripts/cypress/integration/common/3f_link_to_another_record.js
  64. 4
      scripts/cypress/integration/common/4a_table_view_grid_gallery_form.js
  65. 32
      scripts/cypress/integration/common/4b_table_view_share.js
  66. 6
      scripts/cypress/integration/common/4c_form_view_detailed.js
  67. 2
      scripts/cypress/integration/common/4d_table_view_grid_locked.js
  68. 6
      scripts/cypress/integration/common/4e_form_view_share.js
  69. 10
      scripts/cypress/integration/common/4f_grid_view_share.js
  70. 20
      scripts/cypress/integration/common/4f_pg_grid_view_share.js
  71. 2
      scripts/cypress/integration/common/5b_preview_role.js
  72. 4
      scripts/cypress/integration/common/6d_language_validation.js
  73. 2
      scripts/cypress/integration/common/6e_project_operations.js
  74. 6
      scripts/cypress/integration/common/6f_attachments.js
  75. 4
      scripts/cypress/integration/common/6g_base_share.js
  76. 2
      scripts/cypress/integration/common/7a_create_project_from_excel.js
  77. 8
      scripts/cypress/integration/common/7b_import_from_airtable.js
  78. 16
      scripts/cypress/integration/common/8a_webhook.js
  79. 14
      scripts/cypress/integration/common/9a_QuickTest.js
  80. 34
      scripts/cypress/integration/spec/roleValidation.spec.js
  81. 29
      scripts/cypress/plugins/index.js
  82. 42
      scripts/cypress/support/commands.js
  83. 72
      scripts/cypress/support/page_objects/mainPage.js

2
packages/nc-gui/components/cell/DatePicker.vue

@ -67,7 +67,7 @@ const placeholder = computed(() => (isDateInvalid ? 'Invalid date' : ''))
:placeholder="placeholder"
:allow-clear="!readOnly"
:input-read-only="true"
:dropdown-class-name="randomClass"
:dropdown-class-name="`${randomClass} nc-picker-date`"
:open="readOnly ? false : open"
@click="open = !open"
>

2
packages/nc-gui/components/cell/DateTimePicker.vue

@ -67,7 +67,7 @@ watch(
:placeholder="isDateInvalid ? 'Invalid date' : ''"
:allow-clear="!readOnly"
:input-read-only="true"
:dropdown-class-name="randomClass"
:dropdown-class-name="`${randomClass} nc-picker-datetime`"
:open="readOnly ? false : open"
:disabled="readOnly"
@click="open = !open"

2
packages/nc-gui/components/cell/TimePicker.vue

@ -79,7 +79,7 @@ watch(
:allow-clear="!readOnly"
:input-read-only="true"
:open="readOnly ? false : open"
:popup-class-name="randomClass"
:popup-class-name="`${randomClass} nc-picker-time`"
@click="open = !open"
@ok="open = !open"
>

2
packages/nc-gui/components/cell/YearPicker.vue

@ -66,7 +66,7 @@ const placeholder = computed(() => (isYearInvalid ? 'Invalid year' : ''))
:allow-clear="!readOnly"
:input-read-only="true"
:open="readOnly ? false : open"
:dropdown-class-name="randomClass"
:dropdown-class-name="`${randomClass} nc-picker-year`"
@click="open = !open"
@change="open = !open"
>

8
packages/nc-gui/components/cell/attachment/Modal.vue

@ -58,7 +58,13 @@ function onClick(item: Record<string, any>) {
</script>
<template>
<a-modal v-model:visible="modalVisible" class="nc-attachment-modal" width="80%" :footer="null">
<a-modal
v-model:visible="modalVisible"
class="nc-attachment-modal"
width="80%"
:footer="null"
wrap-class-name="nc-modal-attachment-expand-cell"
>
<template #title>
<div class="flex gap-4">
<div

4
packages/nc-gui/components/dashboard/TreeView.vue

@ -218,7 +218,7 @@ function openTableCreateDialog() {
<template>
<div class="nc-treeview-container flex flex-col">
<a-dropdown :trigger="['contextmenu']">
<a-dropdown :trigger="['contextmenu']" overlay-class-name="nc-dropdown-tree-view-context-menu">
<div class="pt-2 pl-2 pb-2 flex-1 overflow-y-auto flex flex-col scrollbar-thin-dull" :class="{ 'mb-[20px]': isSharedBase }">
<div class="py-1 px-3 flex w-full items-center gap-1 cursor-pointer" @contextmenu="setMenuContext('main')">
<span class="flex-1 text-bold uppercase nc-project-tree text-gray-500 font-weight-bold">
@ -238,7 +238,7 @@ function openTableCreateDialog() {
<span class="text-gray-500 group-hover:(text-primary/100) flex-1 nc-add-new-table">{{ $t('tooltip.addTable') }}</span>
<a-dropdown v-if="!isSharedBase" :trigger="['click']" @click.stop>
<a-dropdown v-if="!isSharedBase" :trigger="['click']" overlay-class-name="nc-dropdown-import-menu" @click.stop>
<MdiDotsVertical class="transition-opacity opacity-0 group-hover:opacity-100 nc-import-menu" />
<template #overlay>

18
packages/nc-gui/components/dashboard/settings/AppStore.vue

@ -72,7 +72,14 @@ onMounted(async () => {
</script>
<template>
<a-modal v-model:visible="showPluginInstallModal" :closable="false" centered min-height="300" :footer="null">
<a-modal
v-model:visible="showPluginInstallModal"
:closable="false"
centered
min-height="300"
:footer="null"
wrap-class-name="nc-modal-plugin-install"
>
<AppInstall
v-if="pluginApp && showPluginInstallModal"
:id="pluginApp.id"
@ -81,7 +88,14 @@ onMounted(async () => {
/>
</a-modal>
<a-modal v-model:visible="showPluginUninstallModal" :closable="false" width="24rem" centered :footer="null">
<a-modal
v-model:visible="showPluginUninstallModal"
:closable="false"
width="24rem"
centered
:footer="null"
wrap-class-name="nc-modal-plugin-uninstall"
>
<div class="flex flex-col h-full">
<div class="flex flex-row justify-center mt-2 text-center w-full text-base">
{{ `Click on confirm to reset ${pluginApp && pluginApp.title}` }}

1
packages/nc-gui/components/dashboard/settings/Modal.vue

@ -159,6 +159,7 @@ watch(
:footer="null"
width="max(90vw, 600px)"
:closable="false"
wrap-class-name="nc-modal-settings"
@cancel="emits('update:modelValue', false)"
>
<!-- Settings -->

8
packages/nc-gui/components/dlg/AirtableImport.vue

@ -231,7 +231,13 @@ onBeforeUnmount(() => {
</script>
<template>
<a-modal v-model:visible="dialogShow" width="max(30vw, 600px)" class="p-2" @keydown.esc="dialogShow = false">
<a-modal
v-model:visible="dialogShow"
width="max(30vw, 600px)"
class="p-2"
wrap-class-name="nc-modal-airtable-import"
@keydown.esc="dialogShow = false"
>
<div class="px-5">
<!-- Quick Import -->
<div class="mt-5 prose-xl font-weight-bold">{{ $t('title.quickImport') }} - AIRTABLE</div>

8
packages/nc-gui/components/dlg/QuickImport.vue

@ -284,7 +284,12 @@ const customReqCbk = (customReqArgs: { file: any; onSuccess: () => void }) => {
</script>
<template>
<a-modal v-model:visible="dialogShow" :width="modalWidth" @keydown.esc="dialogShow = false">
<a-modal
v-model:visible="dialogShow"
:width="modalWidth"
wrap-class-name="nc-modal-quick-import"
@keydown.esc="dialogShow = false"
>
<div class="px-5">
<div class="prose-xl font-weight-bold my-5">{{ importMeta.header }}</div>
@ -298,6 +303,7 @@ const customReqCbk = (customReqArgs: { file: any; onSuccess: () => void }) => {
:import-only="importOnly"
:quick-import-type="importType"
:max-rows-to-parse="importState.parserConfig.maxRowsToParse"
class="nc-quick-import-template-editor"
@import="handleImport"
/>

8
packages/nc-gui/components/dlg/TableCreate.vue

@ -80,7 +80,13 @@ onMounted(() => {
</script>
<template>
<a-modal v-model:visible="dialogShow" width="max(30vw, 600px)" centered @keydown.esc="dialogShow = false">
<a-modal
v-model:visible="dialogShow"
width="max(30vw, 600px)"
centered
wrap-class-name="nc-modal-table-create"
@keydown.esc="dialogShow = false"
>
<template #footer>
<a-button key="back" size="large" @click="dialogShow = false">{{ $t('general.cancel') }}</a-button>

1
packages/nc-gui/components/dlg/TableRename.vue

@ -125,6 +125,7 @@ const renameTable = async () => {
v-model:visible="dialogShow"
:title="$t('activity.renameTable')"
:mask-closable="false"
wrap-class-name="nc-modal-table-rename"
@keydown.esc="dialogShow = false"
@finish="renameTable"
>

2
packages/nc-gui/components/dlg/ViewCreate.vue

@ -140,7 +140,7 @@ async function onSubmit() {
</script>
<template>
<a-modal v-model:visible="vModel" class="!top-[35%]" :confirm-loading="loading">
<a-modal v-model:visible="vModel" class="!top-[35%]" :confirm-loading="loading" wrap-class-name="nc-modal-view-create">
<template #title>
{{ $t('general.create') }} <span class="text-capitalize">{{ typeAlias }}</span> {{ $t('objects.view') }}
</template>

2
packages/nc-gui/components/dlg/ViewDelete.vue

@ -48,7 +48,7 @@ async function onDelete() {
</script>
<template>
<a-modal v-model:visible="vModel" class="!top-[35%]" :confirm-loading="isLoading">
<a-modal v-model:visible="vModel" class="!top-[35%]" :confirm-loading="isLoading" wrap-class-name="nc-modal-view-delete">
<template #title> {{ $t('general.delete') }} {{ $t('objects.view') }} </template>
{{ $t('msg.info.deleteViewConfirmation') }}

2
packages/nc-gui/components/general/HelpAndSupport.vue

@ -27,7 +27,7 @@ const openSwaggerLink = () => {
<a-drawer
v-bind="$attrs"
v-model:visible="showDrawer"
class="h-full relative"
class="h-full relative nc-drawer-help-and-support"
placement="right"
size="small"
:closable="false"

4
packages/nc-gui/components/general/MiniSidebar.vue

@ -28,7 +28,7 @@ const logout = () => {
collapsible
theme="light"
>
<a-dropdown placement="bottom" :trigger="['click']">
<a-dropdown placement="bottom" :trigger="['click']" overlay-class-name="nc-dropdown">
<div class="transition-all duration-200 p-2 cursor-pointer transform hover:scale-105 nc-noco-brand-icon">
<img width="35" alt="NocoDB" src="~/assets/img/icons/512x512-trans.png" />
</div>
@ -60,7 +60,7 @@ const logout = () => {
</a-dropdown>
<div id="sidebar" ref="sidebar" class="text-white flex-auto flex flex-col items-center w-full">
<a-dropdown :trigger="['contextmenu']" placement="right">
<a-dropdown :trigger="['contextmenu']" placement="right" overlay-class-name="nc-dropdown">
<div :class="[route.name === 'index' ? 'active' : '']" class="nc-mini-sidebar-item" @click="navigateTo('/')">
<MdiFolder class="cursor-pointer transform hover:scale-105 text-2xl" />
</div>

2
packages/nc-gui/components/general/ReleaseInfo.vue

@ -40,7 +40,7 @@ onMounted(async () => await fetchReleaseInfo())
<template>
<div v-if="releaseAlert" class="flex items-center">
<a-dropdown :trigger="['click']" placement="bottom">
<a-dropdown :trigger="['click']" placement="bottom" overlay-class-name="nc-dropdown-upgrade-menu">
<a-button class="!bg-primary !border-none">
<div class="flex gap-1 items-center text-white">
<span class="text-sm font-weight-medium">{{ $t('activity.upgrade.available') }}</span>

6
packages/nc-gui/components/general/language/index.vue

@ -1,5 +1,9 @@
<template>
<a-dropdown class="select-none color-transition cursor-pointer" :trigger="['click']">
<a-dropdown
class="select-none color-transition cursor-pointer"
:trigger="['click']"
overlay-class-name="nc-dropdown-menu-translate"
>
<div v-bind="$attrs" class="flex items-center justify-center">
<MaterialSymbolsTranslate class="md:text-xl nc-menu-translate" />
</div>

1
packages/nc-gui/components/shared-view/AskPassword.vue

@ -33,6 +33,7 @@ const onFinish = async () => {
centered
:footer="null"
:mask-closable="false"
wrap-class-name="nc-modal-shared-view-password-dlg"
@close="vModel = false"
>
<div class="w-full flex flex-col">

6
packages/nc-gui/components/smartsheet-column/SelectOptions.vue

@ -97,7 +97,11 @@ watch(inputs, () => {
<template #item="{ element, index }">
<div class="flex py-1 items-center">
<MdiDragIcon small class="nc-child-draggable-icon handle" />
<a-dropdown v-model:visible="colorMenus[index]" :trigger="['click']">
<a-dropdown
v-model:visible="colorMenus[index]"
:trigger="['click']"
overlay-class-name="nc-dropdown-select-color-options"
>
<template #overlay>
<GeneralColorPicker v-model="element.color" :pick-button="true" @update:model-value="colorMenus[index] = false" />
</template>

8
packages/nc-gui/components/smartsheet-header/Cell.vue

@ -28,7 +28,13 @@ const editColumnDropdown = ref(false)
<SmartsheetHeaderMenu v-if="!isForm && isUIAllowed('edit-column')" @edit="editColumnDropdown = true" />
</template>
<a-dropdown v-model:visible="editColumnDropdown" class="h-full" :trigger="['click']" placement="bottomRight">
<a-dropdown
v-model:visible="editColumnDropdown"
class="h-full"
:trigger="['click']"
placement="bottomRight"
overlay-class-name="nc-dropdown-edit-column"
>
<div />
<template #overlay>
<SmartsheetColumnEditOrAddProvider

2
packages/nc-gui/components/smartsheet-header/Menu.vue

@ -61,7 +61,7 @@ const setAsPrimaryValue = async () => {
</script>
<template>
<a-dropdown v-if="!isLocked" placement="bottomRight" :trigger="['click']">
<a-dropdown v-if="!isLocked" placement="bottomRight" :trigger="['click']" overlay-class-name="nc-dropdown-column-operations">
<MdiMenuDown class="h-full text-grey nc-ui-dt-dropdown cursor-pointer outline-0" />
<template #overlay>

8
packages/nc-gui/components/smartsheet-header/VirtualCell.vue

@ -115,7 +115,13 @@ const tooltipMsg = computed(() => {
<SmartsheetHeaderMenu v-if="!isForm && isUIAllowed('edit-column')" :virtual="true" @edit="editColumnDropdown = true" />
</template>
<a-dropdown v-model:visible="editColumnDropdown" class="h-full" :trigger="['click']" placement="bottomRight">
<a-dropdown
v-model:visible="editColumnDropdown"
class="h-full"
:trigger="['click']"
placement="bottomRight"
overlay-class-name="nc-dropdown-edit-column"
>
<div />
<template #overlay>
<SmartsheetColumnEditOrAddProvider

3
packages/nc-gui/components/smartsheet-toolbar/ColumnFilter.vue

@ -156,6 +156,7 @@ defineExpose({
:dropdown-match-select-width="false"
class="shrink grow-0"
placeholder="Group op"
dropdown-class-name="nc-dropdown-filter-logical-op-group"
@click.stop
@change="saveOrUpdate(filter, i)"
>
@ -203,6 +204,7 @@ defineExpose({
class="h-full"
hide-details
:disabled="filter.readOnly"
dropdown-class-name="nc-dropdown-filter-logical-op"
@click.stop
@change="filterUpdateCondition(filter, i)"
>
@ -230,6 +232,7 @@ defineExpose({
variant="solo"
:disabled="filter.readOnly"
hide-details
dropdown-class-name="nc-dropdown-filter-comp-op"
@change="filterUpdateCondition(filter, i)"
>
<a-select-option v-for="compOp in comparisonOpList" :key="compOp.value" :value="compOp.value" class="">

2
packages/nc-gui/components/smartsheet-toolbar/ColumnFilterMenu.vue

@ -51,7 +51,7 @@ const filterAutoSaveLoc = computed({
</script>
<template>
<a-dropdown :trigger="['click']">
<a-dropdown :trigger="['click']" overlay-class-name="nc-dropdown-filter-menu">
<div :class="{ 'nc-badge nc-active-btn': filtersLength }">
<a-button v-t="['c:filter']" class="nc-filter-menu-btn nc-toolbar-btn txt-sm" :disabled="isLocked">
<div class="flex items-center gap-1">

2
packages/nc-gui/components/smartsheet-toolbar/Export.vue

@ -1,5 +1,5 @@
<template>
<a-dropdown :trigger="['click']">
<a-dropdown :trigger="['click']" overlay-class-name="nc-dropdown-actions-menu">
<a-button v-t="['c:actions']" class="nc-actions-menu-btn nc-toolbar-btn">
<div class="flex gap-2 items-center">
<MdiDownload class="group-hover:text-accent text-gray-500" />

2
packages/nc-gui/components/smartsheet-toolbar/FieldsMenu.vue

@ -116,7 +116,7 @@ const getIcon = (c: ColumnType) =>
</script>
<template>
<a-dropdown :trigger="['click']">
<a-dropdown :trigger="['click']" overlay-class-name="nc-dropdown-fields-menu">
<div :class="{ 'nc-badge nc-active-btn': isAnyFieldHidden }">
<a-button v-t="['c:fields']" class="nc-fields-menu-btn nc-toolbar-btn" :disabled="isLocked">
<div class="flex items-center gap-1">

8
packages/nc-gui/components/smartsheet-toolbar/MoreActions.vue

@ -166,7 +166,13 @@ const exportFile = async (exportType: ExportTypes) => {
<WebhookDrawer v-if="showWebhookDrawer" v-model="showWebhookDrawer" />
<a-modal v-model:visible="sharedViewListDlg" :title="$t('activity.listSharedView')" width="max(900px,60vw)" :footer="null">
<a-modal
v-model:visible="sharedViewListDlg"
:title="$t('activity.listSharedView')"
width="max(900px,60vw)"
:footer="null"
wrap-class-name="nc-modal-shared-view-list"
>
<SmartsheetToolbarSharedViewList v-if="sharedViewListDlg" />
</a-modal>
</div>

1
packages/nc-gui/components/smartsheet-toolbar/ShareView.vue

@ -132,6 +132,7 @@ watch(passwordProtected, (value) => {
:title="$t('msg.info.privateLink')"
:footer="null"
width="min(100vw,640px)"
wrap-class-name="nc-modal-share-view"
>
<div class="share-link-box nc-share-link-box bg-primary-50">
<div class="flex-1 h-min text-xs">{{ sharedViewUrl }}</div>

2
packages/nc-gui/components/smartsheet-toolbar/SortListMenu.vue

@ -41,7 +41,7 @@ watch(
</script>
<template>
<a-dropdown offset-y class="" :trigger="['click']" overlay-class-name="sort-menu-overlay">
<a-dropdown offset-y class="" :trigger="['click']" overlay-class-name="nc-dropdown-sort-menu">
<div :class="{ 'nc-badge nc-active-btn': sorts?.length }">
<a-button v-t="['c:sort']" class="nc-sort-menu-btn nc-toolbar-btn" :disabled="isLocked"
><div class="flex items-center gap-1">

10
packages/nc-gui/components/smartsheet-toolbar/ViewActions.vue

@ -81,7 +81,7 @@ const { isSqlView } = useSmartsheetStoreOrThrow()
<template>
<div>
<a-dropdown :trigger="['click']">
<a-dropdown :trigger="['click']" overlay-class-name="nc-dropdown-actions-menu">
<a-button v-t="['c:actions']" class="nc-actions-menu-btn nc-toolbar-btn">
<div class="flex gap-2 items-center">
<component
@ -221,7 +221,13 @@ const { isSqlView } = useSmartsheetStoreOrThrow()
<WebhookDrawer v-if="showWebhookDrawer" v-model="showWebhookDrawer" />
<a-modal v-model:visible="sharedViewListDlg" :title="$t('activity.listSharedView')" width="max(900px,60vw)" :footer="null">
<a-modal
v-model:visible="sharedViewListDlg"
:title="$t('activity.listSharedView')"
width="max(900px,60vw)"
:footer="null"
wrap-class-name="nc-modal-shared-view-list"
>
<SmartsheetToolbarSharedViewList v-if="sharedViewListDlg" />
</a-modal>
<SmartsheetApiSnippet v-model="showApiSnippetDrawer" />

2
packages/nc-gui/components/smartsheet/ApiSnippet.vue

@ -136,7 +136,7 @@ watch($$(activeLang), (newLang) => {
<template>
<a-drawer
v-model:visible="vModel"
class="h-full relative"
class="h-full relative nc-drawer-api-snippet"
style="color: red"
placement="right"
size="large"

2
packages/nc-gui/components/smartsheet/Form.vue

@ -470,7 +470,7 @@ onMounted(async () => {
<!-- Drag and drop fields here to hide -->
{{ $t('msg.info.dragDropHide') }}
</div>
<a-dropdown v-model:visible="showColumnDropdown" :trigger="['click']">
<a-dropdown v-model:visible="showColumnDropdown" :trigger="['click']" overlay-class-name="nc-dropdown-form-add-column">
<a-button type="link" class="w-full caption mt-2" size="large" @click.stop="showColumnDropdown = true">
<div class="flex items-center prose-sm justify-center text-gray-400">
<mdi-plus />

12
packages/nc-gui/components/smartsheet/Grid.vue

@ -363,7 +363,11 @@ onBeforeUnmount(async () => {
<a-spin size="large" />
</div>
<div v-else class="nc-grid-wrapper min-h-0 flex-1 scrollbar-thin-dull">
<a-dropdown v-model:visible="contextMenu" :trigger="isSqlView ? [] : ['contextmenu']">
<a-dropdown
v-model:visible="contextMenu"
:trigger="isSqlView ? [] : ['contextmenu']"
overlay-class-name="nc-dropdown-grid-context-menu"
>
<table
ref="smartTable"
class="xc-row-table nc-grid backgroundColorDefault !h-auto bg-white"
@ -411,7 +415,11 @@ onBeforeUnmount(async () => {
class="cursor-pointer"
@click.stop="addColumnDropdown = true"
>
<a-dropdown v-model:visible="addColumnDropdown" :trigger="['click']">
<a-dropdown
v-model:visible="addColumnDropdown"
:trigger="['click']"
overlay-class-name="nc-dropdown-grid-add-column"
>
<div class="h-full w-[60px] flex items-center justify-center">
<MdiPlus class="text-sm nc-column-add" />
</div>

1
packages/nc-gui/components/smartsheet/expanded-form/index.vue

@ -108,6 +108,7 @@ export default {
width="min(90vw,1000px)"
:body-style="{ 'padding': 0, 'display': 'flex', 'flex-direction': 'column' }"
:closable="false"
class="nc-drawer-expanded-form"
>
<Header @cancel="onClose" />
<div class="!bg-gray-100 rounded flex-1">

2
packages/nc-gui/components/smartsheet/sidebar/toolbar/DebugMeta.vue

@ -18,7 +18,7 @@ const localTables = tables.value.filter((t) => metas[t.id as string])
<mdi-bug-outline class="cursor-pointer" @click="editorOpen = true" />
</a-tooltip>
<a-modal v-model:visible="editorOpen" :footer="null" width="80%">
<a-modal v-model:visible="editorOpen" :footer="null" width="80%" wrap-class-name="nc-modal-debug-meta">
<a-tabs v-model:activeKey="tabKey" type="card" closeable="false" class="shadow-sm">
<a-tab-pane v-for="table in localTables" :key="table.id" :tab="table.title">
<MonacoEditor v-model="metas[table.id]" class="h-max-[70vh]" :read-only="true" />

20
packages/nc-gui/components/tabs/auth/ApiTokenManagement.vue

@ -98,7 +98,14 @@ onMounted(() => {
</script>
<template>
<a-modal v-model:visible="showNewTokenModal" :closable="false" width="28rem" centered :footer="null">
<a-modal
v-model:visible="showNewTokenModal"
:closable="false"
width="28rem"
centered
:footer="null"
wrap-class-name="nc-modal-generate-token"
>
<div class="relative flex flex-col h-full">
<a-button type="text" class="!absolute top-0 right-0 rounded-md -mt-2 -mr-3" @click="showNewTokenModal = false">
<template #icon>
@ -131,7 +138,14 @@ onMounted(() => {
</a-form>
</div>
</a-modal>
<a-modal v-model:visible="showDeleteTokenModal" :closable="false" width="28rem" centered :footer="null">
<a-modal
v-model:visible="showDeleteTokenModal"
:closable="false"
width="28rem"
centered
:footer="null"
wrap-class-name="nc-modal-delete-token"
>
<div class="flex flex-col h-full">
<div class="flex flex-row justify-center mt-2 text-center w-full text-base">This action will remove this API Token</div>
<div class="flex mt-6 justify-center space-x-2">
@ -195,7 +209,7 @@ onMounted(() => {
</a-button>
</a-tooltip>
<a-dropdown :trigger="['click']" class="flex" placement="bottomRight">
<a-dropdown :trigger="['click']" class="flex" placement="bottomRight" overlay-class-name="nc-dropdown-api-token-mgmt">
<div class="flex flex-row items-center">
<a-button type="text" class="!px-0">
<div class="flex flex-row items-center h-[1.2rem]">

11
packages/nc-gui/components/tabs/auth/UserManagement.vue

@ -173,7 +173,14 @@ watchDebounced(searchText, () => loadUsers(), { debounce: 300, maxWait: 600 })
@closed="showUserModal = false"
@reload="loadUsers()"
/>
<a-modal v-model:visible="showUserDeleteModal" :closable="false" width="28rem" centered :footer="null">
<a-modal
v-model:visible="showUserDeleteModal"
:closable="false"
width="28rem"
centered
:footer="null"
wrap-class-name="nc-modal-delete-user"
>
<div class="flex flex-col h-full">
<div class="flex flex-row justify-center mt-2 text-center w-full text-base">
This action will remove this user from this project
@ -282,7 +289,7 @@ watchDebounced(searchText, () => loadUsers(), { debounce: 300, maxWait: 600 })
</a-button>
</a-tooltip>
<a-dropdown :trigger="['click']" class="flex" placement="bottomRight">
<a-dropdown :trigger="['click']" class="flex" placement="bottomRight" overlay-class-name="nc-dropdown-user-mgmt">
<div class="flex flex-row items-center">
<a-button type="text" class="!px-0">
<div class="flex flex-row items-center h-[1.2rem]">

2
packages/nc-gui/components/tabs/auth/user-management/ShareBase.vue

@ -195,7 +195,7 @@ onMounted(() => {
<!-- Generate publicly shareable readonly base -->
<div class="flex text-xs text-gray-500 mt-2 justify-start ml-2">{{ $t('msg.info.generatePublicShareableReadonlyBase') }}</div>
<div class="mt-4 flex flex-row justify-between mx-1">
<a-dropdown v-model="showEditBaseDropdown" class="flex">
<a-dropdown v-model="showEditBaseDropdown" class="flex" overlay-class-name="nc-dropdown-shared-base-toggle">
<a-button>
<div class="flex flex-row items-center space-x-2 nc-disable-shared-base">
<div v-if="base?.uuid">{{ $t('activity.shareBase.enable') }}</div>

10
packages/nc-gui/components/tabs/auth/user-management/UsersModal.vue

@ -130,7 +130,15 @@ const clickInviteMore = () => {
</script>
<template>
<a-modal :footer="null" centered :visible="show" :closable="false" width="max(50vw, 44rem)" @cancel="emit('closed')">
<a-modal
:footer="null"
centered
:visible="show"
:closable="false"
width="max(50vw, 44rem)"
wrap-class-name="nc-modal-invite-user-and-share-base"
@cancel="emit('closed')"
>
<div class="flex flex-col">
<div class="flex flex-row justify-between items-center pb-1.5 mb-2 border-b-1 w-full">
<a-typography-title class="select-none" :level="4"> {{ $t('activity.share') }}: {{ project.title }} </a-typography-title>

9
packages/nc-gui/components/virtual-cell/components/ListChildItems.vue

@ -87,7 +87,14 @@ watch(
</script>
<template>
<component :is="container" v-model:visible="vModel" :footer="null" title="Child list" :body-style="{ padding: 0 }">
<component
:is="container"
v-model:visible="vModel"
:footer="null"
title="Child list"
:body-style="{ padding: 0 }"
wrap-class-name="nc-modal-child-list"
>
<div class="max-h-[max(calc(100vh_-_300px)_,500px)] flex flex-col py-6">
<div class="flex mb-4 items-center gap-2 px-12">
<div class="flex-1" />

8
packages/nc-gui/components/virtual-cell/components/ListItems.vue

@ -104,7 +104,13 @@ watch(expandedFormDlg, (nexVal) => {
</script>
<template>
<a-modal v-model:visible="vModel" :footer="null" :title="$t('activity.linkRecord')" :body-style="{ padding: 0 }">
<a-modal
v-model:visible="vModel"
:footer="null"
:title="$t('activity.linkRecord')"
:body-style="{ padding: 0 }"
wrap-class-name="nc-modal-link-record"
>
<div class="max-h-[max(calc(100vh_-_300px)_,500px)] flex flex-col py-6">
<div class="flex mb-4 items-center gap-2 px-12">
<a-input

1
packages/nc-gui/components/webhook/Drawer.vue

@ -29,6 +29,7 @@ async function editHook(hook: Record<string, any>) {
placement="right"
width="700px"
:body-style="{ background: 'rgba(67, 81, 232, 0.05)', padding: '0px 0px', overflow: 'hidden' }"
class="nc-drawer-webhook"
@keydown.esc="vModel = false"
>
<a-layout class="">

1
packages/nc-gui/composables/useTable.ts

@ -63,6 +63,7 @@ export function useTable(onTableCreate?: (tableMeta: TableType) => void) {
// 'Click Submit to Delete The table'
Modal.confirm({
title: `${t('msg.info.deleteTableConfirmation')} : ${table.title}?`,
wrapClassName: 'nc-modal-table-delete',
okText: t('general.yes'),
okType: 'danger',
cancelText: t('general.no'),

2
packages/nc-gui/layouts/base.vue

@ -69,7 +69,7 @@ hooks.hook('page:finish', () => {
</a-tooltip>
<template v-if="signedIn && !isSharedBase">
<a-dropdown :trigger="['click']">
<a-dropdown :trigger="['click']" overlay-class-name="nc-dropdown-user-accounts-menu">
<MdiDotsVertical class="md:text-xl cursor-pointer hover:text-accent nc-menu-accounts text-white" @click.prevent />
<template #overlay>

4
packages/nc-gui/lib/enums.ts

@ -50,8 +50,8 @@ export enum Language {
tr = 'Türk',
uk = 'Українська',
vi = 'Tiếng Việt',
zh_Hans = '简体中文',
zh_Hant = '繁體中文',
'zh-Hans' = '简体中文',
'zh-Hant' = '繁體中文',
}
export enum NavigateDir {

7
packages/nc-gui/pages/[projectType]/[projectId]/index.vue

@ -193,7 +193,12 @@ if (type && name) {
<img alt="NocoDB" src="~/assets/img/icons/512x512-trans.png" />
</a>
<a-dropdown class="h-full min-w-0 flex-1" :trigger="['click']" placement="bottom">
<a-dropdown
class="h-full min-w-0 flex-1"
:trigger="['click']"
placement="bottom"
overlay-class-name="nc-dropdown-project-menu"
>
<div
:style="{ width: isOpen ? 'calc(100% - 40px) pr-2' : '100%' }"
:class="[isOpen ? '' : 'justify-center']"

1
packages/nc-gui/pages/[projectType]/form/[viewId]/index.vue

@ -136,6 +136,7 @@ function isRequired(_columnObj: Record<string, any>, required = false) {
centered
:footer="null"
:mask-closable="false"
wrap-class-name="nc-modal-shared-form-password-dlg"
@close="passwordDlg = false"
>
<div class="w-full flex flex-col">

9
packages/nc-gui/pages/index/index/create-external.vue

@ -539,7 +539,13 @@ onMounted(() => {
</a-form-item>
</a-form>
<a-modal v-model:visible="configEditDlg" :title="$t('activity.editConnJson')" width="600px" @ok="handleOk">
<a-modal
v-model:visible="configEditDlg"
:title="$t('activity.editConnJson')"
width="600px"
wrap-class-name="nc-modal-edit-connection-json"
@ok="handleOk"
>
<MonacoEditor v-if="configEditDlg" v-model="customFormState" class="h-[400px] w-full" />
</a-modal>
@ -550,6 +556,7 @@ onMounted(() => {
width="600px"
:ok-text="$t('general.ok')"
:cancel-text="$t('general.cancel')"
wrap-class-name="nc-modal-connection-url"
@ok="handleImportURL"
>
<a-input v-model:value="importURL" />

3
packages/nc-gui/pages/index/index/index.vue

@ -48,6 +48,7 @@ const deleteProject = (project: ProjectType) => {
Modal.confirm({
title: `Do you want to delete '${project.title}' project?`,
wrapClassName: 'nc-modal-project-delete',
okText: 'Yes',
okType: 'danger',
cancelText: 'No',
@ -136,7 +137,7 @@ const getProjectPrimary = (project: ProjectType) => {
<div class="flex-1" />
<a-dropdown v-if="isUIAllowed('projectCreate', true)" :trigger="['click']">
<a-dropdown v-if="isUIAllowed('projectCreate', true)" :trigger="['click']" overlay-class-name="nc-dropdown-create-project">
<button class="nc-new-project-menu">
<span class="flex items-center w-full">
{{ $t('title.newProj') }}

2
packages/nc-gui/pages/projects/index/index.vue

@ -71,7 +71,7 @@ const formatTitle = (title: string) =>
<div v-for="(project, i) of projects" :key="project.id" class="group flex flex-col items-center gap-2">
<div class="thumbnail" :style="{ '--thumbnail-color': getColorByIndex(i) }" @click="openProject(project)">
{{ formatTitle(project.title) }}
<a-dropdown @click.stop>
<a-dropdown overlay-class-name="nc-dropdown-project-operations" @click.stop>
<MdiMenuDown class="menu-icon" />
<template #overlay>
<a-menu>

147
scripts/cypress/integration/common/00_pre_configurations.js

@ -168,81 +168,88 @@ export const genTest = (apiType, dbType) => {
loginPage.signUp(roles.owner.credentials);
});
const createProject = (proj) => {
it(`Create ${proj.basic.name} project`, () => {
// click home button
cy.get(".nc-noco-brand-icon").click();
cy.get(".ant-table-content").then((obj) => {
function cy_createProjectBlock(proj, apiType, dbType) {
// click home button
cy.get(".nc-noco-brand-icon").click();
cy.get(".ant-table-content").then((obj) => {
// if project already created, open
// else, create a new one
if (true == obj[0].innerHTML.includes(proj.basic.name)) {
projectsPage.openProject(proj.basic.name);
// if project already created, open
// else, create a new one
if (true == obj[0].innerHTML.includes(proj.basic.name)) {
projectsPage.openProject(proj.basic.name);
let projId;
if (dbType === "xcdb") {
let query = `SELECT prefix from nc_projects_v2 where title = "sampleREST"; `;
cy.task("sqliteExecReturnValue", query).then(
(resolve) => {
cy.log(resolve);
projId = resolve.prefix;
setProjectString(projId);
cy.log(projId);
}
);
}
} else {
projectsPage.createProject(proj.basic, proj.config);
cy.wait(5000);
if (dbType === "xcdb") {
// store base URL- to re-visit and delete form view later
let projId;
if (dbType === "xcdb") {
let query = `SELECT prefix from nc_projects_v2 where title = "sampleREST"; `;
cy.task("sqliteExecReturnValue", query).then(
(resolve) => {
cy.log(resolve);
projId = resolve.prefix;
setProjectString(projId);
cy.log(projId);
}
);
}
} else {
projectsPage.createProject(proj.basic, proj.config);
cy.wait(5000);
if (dbType === "xcdb") {
// store base URL- to re-visit and delete form view later
let projId;
cy.url()
.then((url) => {
// project prefix code can include "_"
// projId = url.split("_")[1].split("?")[0];
let startIdx = url.indexOf("_");
let endIdx = url.indexOf("?");
projId = url.slice(startIdx + 1, endIdx);
cy.url()
.then((url) => {
// project prefix code can include "_"
// projId = url.split("_")[1].split("?")[0];
let startIdx = url.indexOf("_");
let endIdx = url.indexOf("?");
projId = url.slice(startIdx + 1, endIdx);
let query = `SELECT prefix from nc_projects_v2 where title = "sampleREST"; `;
cy.task("sqliteExecReturnValue", query)
.then((resolve) => {
cy.log(resolve);
projId = resolve.prefix;
cy.log(projId);
setProjectString(projId);
})
.then(() => {
let query =
prepareSqliteQuery(projId);
for (
let i = 0;
i < query.length;
i++
) {
cy.task("sqliteExec", query[i]);
cy.wait(1000);
}
});
})
.then(() => {
cy.log(projId);
mainPage.openMetaTab();
mainPage.metaSyncValidate(
`${projId}actor`,
`New table, New relation added`
);
mainPage.closeMetaTab();
});
}
let query = `SELECT prefix from nc_projects_v2 where title = "sampleREST"; `;
cy.task("sqliteExecReturnValue", query)
.then((resolve) => {
cy.log(resolve);
projId = resolve.prefix;
cy.log(projId);
setProjectString(projId);
})
.then(() => {
let query =
prepareSqliteQuery(projId);
for (
let i = 0;
i < query.length;
i++
) {
cy.task("sqliteExec", query[i]);
cy.wait(1000);
}
});
})
.then(() => {
cy.log(projId);
mainPage.openMetaTab();
mainPage.metaSyncValidate(
`${projId}actor`,
`New table, New relation added`
);
mainPage.closeMetaTab();
});
}
});
// hack to disable dark mode
cy.fileHook();
}
});
}
const createProject = (proj) => {
it(`Create ${proj.basic.name} project`, () => {
if(dbType === "postgres") {
// wait for docker compose to start
cy.task(
'pgExecTest',
`SELECT 1+1`, {timeout: 120000}
).then(() => cy_createProjectBlock(proj, apiType, dbType));
}
else {
cy_createProjectBlock(proj, apiType, dbType);
}
});
};

6
scripts/cypress/integration/common/1b_table_column_operations.js

@ -83,7 +83,7 @@ export const genTest = (apiType, dbType) => {
cy.get(".nc-column-edit").should("not.be.visible");
// rename column and verify
cy.getActiveMenu().find('input.nc-column-name-input', { timeout: 3000 })
cy.getActiveMenu(".nc-dropdown-edit-column").find('input.nc-column-name-input', { timeout: 3000 })
.should('exist')
.clear()
.type(updatedColName);
@ -140,7 +140,7 @@ export const genTest = (apiType, dbType) => {
.rightclick({ force: true });
// delete row
cy.getActiveMenu()
cy.getActiveMenu(".nc-dropdown-grid-context-menu")
.find('.ant-dropdown-menu-item:contains("Delete Row")')
.first()
.click({ force: true });
@ -161,7 +161,7 @@ export const genTest = (apiType, dbType) => {
// delete selected rows
mainPage.getCell("Title", 3).rightclick({ force: true });
cy.getActiveMenu()
cy.getActiveMenu(".nc-dropdown-grid-context-menu")
.contains("Delete Selected Rows")
.click({ force: true });

2
scripts/cypress/integration/common/1d_pg_table_view_drag_drop_reorder.js

@ -87,7 +87,7 @@ export const genTest = (apiType, dbType) => {
cy.snipActiveModal(`Modal_createView_${viewType}`);
// Pop up window, click Submit (accepting default name for view)
cy.getActiveModal().find("button:contains(Submit)").click();
cy.getActiveModal(".nc-modal-view-create").find("button:contains(Submit)").click();
cy.toastWait("View created successfully");
}

2
scripts/cypress/integration/common/1d_table_view_drag_drop_reorder.js

@ -90,7 +90,7 @@ export const genTest = (apiType, dbType) => {
cy.snipActiveModal(`Modal_createView_${viewType}`);
// Pop up window, click Submit (accepting default name for view)
cy.getActiveModal().find("button:contains(Submit)").click();
cy.getActiveModal(".nc-modal-view-create").find("button:contains(Submit)").click();
cy.toastWait("View created successfully");
}

12
scripts/cypress/integration/common/2a_table_with_belongs_to_colulmn.js

@ -59,26 +59,26 @@ export const genTest = (apiType, dbType) => {
});
it("Expand Link record, validate", () => {
cy.getActiveModal()
cy.getActiveModal(".nc-modal-child-list")
.find("button:contains(Link to 'City')")
.click()
.then(() => {
// Link record form validation
cy.getActiveModal().contains("Link record").should("exist");
cy.getActiveModal()
cy.getActiveModal(".nc-modal-link-record").contains("Link record").should("exist");
cy.getActiveModal(".nc-modal-link-record")
.find(".nc-reload")
.should("exist");
cy.getActiveModal()
cy.getActiveModal(".nc-modal-link-record")
.find('button:contains("Add new record")')
.should("exist");
cy.getActiveModal()
cy.getActiveModal(".nc-modal-link-record")
.find(".ant-card")
.eq(0)
.contains("A Corua (La Corua)")
.should("exist");
cy.getActiveModal()
cy.getActiveModal(".nc-modal-link-record")
.find("button.ant-modal-close")
.click();
// .then(() => {

16
scripts/cypress/integration/common/2b_table_with_m2m_column.js

@ -57,7 +57,7 @@ export const genTest = (apiType, dbType) => {
// cy.getActiveModal()
// .find("button:contains(Link to 'Film')")
// .should("exist");
cy.getActiveModal()
cy.getActiveModal(".nc-modal-child-list")
.find(".ant-card")
.eq(0)
.contains("ACADEMY DINOSAUR")
@ -65,24 +65,24 @@ export const genTest = (apiType, dbType) => {
});
it('Expand "Link to" record, validate', () => {
cy.getActiveModal()
cy.getActiveModal(".nc-modal-child-list")
.find("button:contains(Link to 'Film')")
.click()
.then(() => {
// Link record form validation
cy.getActiveModal().contains("Link record").should("exist");
cy.getActiveModal()
cy.getActiveModal(".nc-modal-link-record").contains("Link record").should("exist");
cy.getActiveModal(".nc-modal-link-record")
.find(".nc-reload")
.should("exist");
cy.getActiveModal()
cy.getActiveModal(".nc-modal-link-record")
.find('button:contains("Add new record")')
.should("exist");
cy.getActiveModal()
cy.getActiveModal(".nc-modal-link-record")
.find(".ant-card")
.eq(0)
.contains("ACE GOLDFINGER")
.should("exist");
cy.getActiveModal().find("button.ant-modal-close").click();
cy.getActiveModal(".nc-modal-link-record").find("button.ant-modal-close").click();
});
});
@ -92,7 +92,7 @@ export const genTest = (apiType, dbType) => {
mainPage.getCell("Film List", 1).should("exist").trigger("mouseover").click();
cy.get('.nc-action-icon').eq(0).should('exist').click({ force: true });
cy.getActiveModal()
cy.getActiveModal(".nc-modal-child-list")
.find(".ant-card")
.eq(0)
.contains("ACADEMY DINOSAUR", { timeout: 2000 })

8
scripts/cypress/integration/common/3a_filter_sort_fields_operations.js

@ -82,7 +82,7 @@ export const genTest = (apiType, dbType) => {
it("Delete Row", () => {
// delete row added in previous step
mainPage.getCell("Country", 10).rightclick();
cy.getActiveMenu().contains("Delete Row").click();
cy.getActiveMenu(".nc-dropdown-grid-context-menu").contains("Delete Row").click();
// cy.toastWait('Deleted row successfully')
@ -99,7 +99,7 @@ export const genTest = (apiType, dbType) => {
mainPage.getPagination(5).click();
mainPage.getCell("Country", 9).rightclick({ force: true });
cy.getActiveMenu()
cy.getActiveMenu(".nc-dropdown-grid-context-menu")
.contains("Insert New Row")
.click({ force: true });
mainPage
@ -109,7 +109,7 @@ export const genTest = (apiType, dbType) => {
.type("Test Country-1{enter}");
mainPage.getCell("Country", 10).rightclick({ force: true });
cy.getActiveMenu()
cy.getActiveMenu(".nc-dropdown-grid-context-menu")
.contains("Insert New Row")
.click({ force: true });
mainPage
@ -142,7 +142,7 @@ export const genTest = (apiType, dbType) => {
.eq(11).click({ force: true });
mainPage.getCell("Country", 10).rightclick({ force: true });
cy.getActiveMenu()
cy.getActiveMenu(".nc-dropdown-grid-context-menu")
.contains("Delete Selected Rows")
.click({ force: true });

15
scripts/cypress/integration/common/3b_formula_column.js

@ -13,17 +13,6 @@ export const genTest = (apiType, dbType) => {
//
before(() => {
// loginPage.loginAndOpenProject(apiType, dbType)
mainPage.tabReset();
// open a table to work on views
//
// // kludge: wait for page load to finish
// cy.wait(1000);
// // close team & auth tab
// cy.get('button.ant-tabs-tab-remove').should('exist').click();
// cy.wait(1000);
cy.openTableTab("City", 25);
});
@ -59,7 +48,7 @@ export const genTest = (apiType, dbType) => {
force: true,
});
cy.getActiveMenu().find('input.nc-column-name-input', { timeout: 3000 })
cy.getActiveMenu(".nc-dropdown-grid-add-column").find('input.nc-column-name-input', { timeout: 3000 })
.should('exist')
.clear()
.type(columnName);
@ -91,7 +80,7 @@ export const genTest = (apiType, dbType) => {
cy.get(".nc-column-edit").click();
cy.get(".nc-column-edit").should("not.be.visible");
cy.getActiveMenu().find('input.nc-column-name-input', { timeout: 3000 })
cy.getActiveMenu(".nc-dropdown-edit-column").find('input.nc-column-name-input', { timeout: 3000 })
.should('exist')
.clear()
.type(newName);

4
scripts/cypress/integration/common/3c_lookup_column.js

@ -44,7 +44,7 @@ export const genTest = (apiType, dbType) => {
force: true,
});
cy.getActiveMenu().find('input.nc-column-name-input', { timeout: 3000 })
cy.getActiveMenu(".nc-dropdown-grid-add-column").find('input.nc-column-name-input', { timeout: 3000 })
.should('exist')
.clear()
.type(childCol);
@ -54,11 +54,9 @@ export const genTest = (apiType, dbType) => {
// Configure Child table & column names
fetchParentFromLabel("Child table");
cy.getActiveSelection().find('.ant-select-item-option').contains(childTable).click();
// cy.getActiveMenu().contains(childTable).click();
fetchParentFromLabel("Child column");
cy.getActiveSelection().find('.ant-select-item-option').contains(childCol).click();
// cy.getActiveMenu().contains(childCol).click();
cy.get(".ant-btn-primary").contains("Save").should('exist').click();
cy.toastWait(`Column created`);

2
scripts/cypress/integration/common/3d_rollup_column.js

@ -50,7 +50,7 @@ export const genTest = (apiType, dbType) => {
force: true,
});
cy.getActiveMenu().find('input.nc-column-name-input', { timeout: 3000 })
cy.getActiveMenu(".nc-dropdown-grid-add-column").find('input.nc-column-name-input', { timeout: 3000 })
.should('exist')
.clear()
.type(columnName);

5
scripts/cypress/integration/common/3e_duration_column.js

@ -44,7 +44,7 @@ export const genTest = (apiType, dbType) => {
force: true,
});
cy.getActiveMenu().find('input.nc-column-name-input', { timeout: 3000 })
cy.getActiveMenu(".nc-dropdown-grid-add-column").find('input.nc-column-name-input', { timeout: 3000 })
.should('exist')
.clear()
.type(columnName);
@ -54,7 +54,6 @@ export const genTest = (apiType, dbType) => {
// Configure Duration format
fetchParentFromLabel("Duration Format");
cy.getActiveSelection().find('.ant-select-item-option').contains(durationFormat).click();
// cy.getActiveMenu().contains(durationFormat).click();
cy.get(".ant-btn-primary").contains("Save").should('exist').click();
cy.toastWait(`Column created`);
@ -80,7 +79,7 @@ export const genTest = (apiType, dbType) => {
cy.get(".nc-column-edit").should("not.be.visible");
// rename column and verify
cy.getActiveMenu().find('input.nc-column-name-input', { timeout: 3000 })
cy.getActiveMenu(".nc-dropdown-column-operations").find('input.nc-column-name-input', { timeout: 3000 })
.should('exist')
.clear()
.type(newName);

20
scripts/cypress/integration/common/3f_link_to_another_record.js

@ -5,7 +5,7 @@ import { isTestSuiteActive } from "../../support/page_objects/projectConstants";
export const genTest = (apiType, dbType) => {
if (!isTestSuiteActive(apiType, dbType)) return;
describe(`${apiType.toUpperCase()} api - RollUp column`, () => {
describe(`${apiType.toUpperCase()} api - Link to another record`, () => {
function fetchParentFromLabel(label) {
cy.get("label").contains(label).parents(".ant-row").click();
@ -31,7 +31,7 @@ export const genTest = (apiType, dbType) => {
cy.get(".nc-grid tr > th:last .nc-icon").click();
// Column name
cy.getActiveMenu().find('input.nc-column-name-input', { timeout: 3000 })
cy.getActiveMenu(".nc-dropdown-grid-add-column").find('input.nc-column-name-input', { timeout: 3000 })
.should('exist')
.clear()
.type(columnName);
@ -175,14 +175,14 @@ export const genTest = (apiType, dbType) => {
.should("exist")
.click({ force: true });
cy.wait(1000);
cy.getActiveModal()
cy.getActiveModal(".nc-modal-link-record")
.find('.ant-card').should('exist')
.eq(0).click();
// MM
cy.get(".nc-expand-col-Sheet1.List").find(".ant-btn-primary").click();
cy.wait(1000);
cy.getActiveModal()
cy.getActiveModal(".nc-modal-link-record")
.find('.ant-card').should('exist')
.eq(0).click();
@ -218,7 +218,7 @@ export const genTest = (apiType, dbType) => {
mainPage.getCell("Sheet1", 2)
.find(".nc-action-icon")
.click({ force: true });
cy.getActiveModal()
cy.getActiveModal(".nc-modal-link-record")
.find('.ant-card')
.should('exist')
.eq(1)
@ -230,7 +230,7 @@ export const genTest = (apiType, dbType) => {
.find(".nc-action-icon")
.last()
.click({ force: true });
cy.getActiveModal()
cy.getActiveModal(".nc-modal-link-record")
.find('.ant-card')
.should('exist')
.eq(1)
@ -242,7 +242,7 @@ export const genTest = (apiType, dbType) => {
.find(".nc-action-icon")
.last()
.click({ force: true });
cy.getActiveModal()
cy.getActiveModal(".nc-modal-link-record")
.find('.ant-card')
.should('exist')
.eq(1)
@ -261,7 +261,7 @@ export const genTest = (apiType, dbType) => {
.should("exist")
.click({ force: true });
cy.wait(1000);
cy.getActiveModal()
cy.getActiveModal(".nc-modal-link-record")
.find('.ant-card').should('exist')
.eq(2).click();
@ -269,7 +269,7 @@ export const genTest = (apiType, dbType) => {
cy.get(".nc-expand-col-Sheet1.List")
.find(".ant-btn-primary").click();
cy.wait(1000);
cy.getActiveModal()
cy.getActiveModal(".nc-modal-link-record")
.find('.ant-card').should('exist')
.eq(2).click();
cy.wait(1000);
@ -278,7 +278,7 @@ export const genTest = (apiType, dbType) => {
cy.get(".nc-expand-col-Link2-1hm")
.find(".ant-btn-primary").click();
cy.wait(1000);
cy.getActiveModal()
cy.getActiveModal(".nc-modal-link-record")
.find('.ant-card').should('exist')
.eq(2).click();
cy.wait(1000);

4
scripts/cypress/integration/common/4a_table_view_grid_gallery_form.js

@ -45,7 +45,7 @@ export const genTest = (apiType, dbType) => {
cy.get(`.nc-create-${viewType}-view`).click();
// Pop up window, click Submit (accepting default name for view)
cy.getActiveModal().find(".ant-btn-primary").click();
cy.getActiveModal(".nc-modal-view-create").find(".ant-btn-primary").click();
cy.toastWait("View created successfully");
// kludge: right navbar closes abruptly. force it open again
@ -83,7 +83,7 @@ export const genTest = (apiType, dbType) => {
// click on delete icon (becomes visible on hovering mouse)
cy.get(".nc-view-delete-icon").click({ force: true });
cy.wait(300)
cy.getActiveModal().find('.ant-btn-dangerous').click();
cy.getActiveModal(".nc-modal-view-delete").find('.ant-btn-dangerous').click();
cy.toastWait("View deleted successfully");
// kludge: right navbar closes abruptly. force it open again

32
scripts/cypress/integration/common/4b_table_view_share.js

@ -7,21 +7,21 @@ let linkText = "";
const generateLinkWithPwd = () => {
mainPage.shareView().click();
cy.getActiveModal().find(".ant-modal-title").contains("This view is shared via a private link").should("be.visible");
cy.getActiveModal(".nc-modal-share-view").find(".ant-modal-title").contains("This view is shared via a private link").should("be.visible");
// enable checkbox & feed pwd, save
cy.getActiveModal().find('.ant-collapse').should('exist').click()
cy.getActiveModal().find('.ant-checkbox-input').should('exist').first().then(($el) => {
if (!$el.prop("checked")) {
cy.wrap($el).click({ force: true });
cy.getActiveModal().find('input[type="password"]').clear().type("1");
cy.getActiveModal().find('button:contains("Save password")').click();
cy.toastWait("Successfully updated");
}
cy.getActiveModal(".nc-modal-share-view").find('.ant-collapse').should('exist').click();
cy.getActiveModal(".nc-modal-share-view").find('.ant-checkbox-input').should('exist').first().then(($el) => {
if (!$el.prop("checked")) {
cy.wrap($el).click({ force: true });
cy.getActiveModal(".nc-modal-share-view").find('input[type="password"]').clear().type("1");
cy.getActiveModal(".nc-modal-share-view").find('button:contains("Save password")').click();
cy.toastWait("Successfully updated");
}
});
// copy link text, visit URL
cy.getActiveModal()
cy.getActiveModal(".nc-modal-share-view")
.find(".nc-share-link-box")
.then(($obj) => {
linkText = $obj.text().trim();
@ -62,25 +62,25 @@ export const genTest = (apiType, dbType) => {
baseUrl: null,
});
cy.getActiveModal().should("exist");
cy.getActiveModal(".nc-modal-shared-view-password-dlg").should("exist");
// feed password
cy.getActiveModal().find('input[type="password"]').clear().type("a");
cy.getActiveModal().find('button:contains("Unlock")').click();
cy.getActiveModal(".nc-modal-shared-view-password-dlg").find('input[type="password"]').clear().type("a");
cy.getActiveModal(".nc-modal-shared-view-password-dlg").find('button:contains("Unlock")').click();
// if pwd is incorrect, active modal requesting to feed in password again will persist
cy.getActiveModal().find('button:contains("Unlock")').should('exist');
cy.getActiveModal(".nc-modal-shared-view-password-dlg").find('button:contains("Unlock")').should('exist');
});
// fallover test- use previously opened view & continue verification instead of opening again
it("Share view with correct password", () => {
// feed password
cy.getActiveModal()
cy.getActiveModal(".nc-modal-shared-view-password-dlg")
.find('input[type="password"]')
.clear()
.type("1");
cy.getActiveModal().find('button:contains("Unlock")').click();
cy.getActiveModal(".nc-modal-shared-view-password-dlg").find('button:contains("Unlock")').click();
// if pwd is incorrect, active modal requesting to feed in password again will persist
// cy.getActiveModal().find('button:contains("Unlock")').should('not.exist');

6
scripts/cypress/integration/common/4c_form_view_detailed.js

@ -100,7 +100,7 @@ export const genTest = (apiType, dbType) => {
cy.get(`.nc-create-${viewType}-view`).click();
// Pop up window, click Submit (accepting default name for view)
cy.getActiveModal().find("button:contains(Submit)").click();
cy.getActiveModal(".nc-modal-view-create").find("button:contains(Submit)").click();
cy.toastWait("View created successfully");
@ -420,7 +420,7 @@ export const genTest = (apiType, dbType) => {
// click on delete icon (becomes visible on hovering mouse)
cy.get(".nc-view-delete-icon").click({ force: true });
cy.wait(1000)
cy.getActiveModal().find('.ant-btn-dangerous').click();
cy.getActiveModal(".nc-modal-view-delete").find('.ant-btn-dangerous').click();
cy.toastWait("View deleted successfully");
// confirm if the number of veiw entries is reduced by 1
@ -437,7 +437,7 @@ export const genTest = (apiType, dbType) => {
cy.get(".ant-checkbox").should('exist').eq(13).click({ force: true });
mainPage.getCell("Country", 10).rightclick({ force: true });
cy.getActiveMenu()
cy.getActiveMenu(".nc-dropdown-grid-context-menu")
.contains("Delete Selected Rows")
.click({ force: true });
});

2
scripts/cypress/integration/common/4d_table_view_grid_locked.js

@ -37,7 +37,7 @@ export const genTest = (apiType, dbType) => {
// on menu, collaboration view appears first (at index 0)
// followed by Locked view (at index 1)
cy.get(".nc-actions-menu-btn").click();
cy.getActiveMenu().find('.ant-dropdown-menu-submenu').eq(0).click();
cy.getActiveMenu(".nc-dropdown-actions-menu").find('.ant-dropdown-menu-submenu').eq(0).click();
cy.wait(1000);
cy.get('.nc-locked-menu-item').contains(menuOption).should('exist').click();

6
scripts/cypress/integration/common/4e_form_view_share.js

@ -53,7 +53,7 @@ export const genTest = (apiType, dbType) => {
cy.get(`.nc-create-${viewType}-view`).click();
// Pop up window, click Submit (accepting default name for view)
cy.getActiveModal().find("button:contains(Submit)").click();
cy.getActiveModal(".nc-modal-view-create").find("button:contains(Submit)").click();
cy.toastWait("View created successfully");
@ -108,7 +108,7 @@ export const genTest = (apiType, dbType) => {
mainPage.shareView().click();
// copy link text, visit URL
cy.getActiveModal()
cy.getActiveModal(".nc-modal-share-view")
.should('exist')
.find(".share-link-box")
.contains("/nc/form/", { timeout: 10000 })
@ -210,7 +210,7 @@ export const genTest = (apiType, dbType) => {
// click on delete icon (becomes visible on hovering mouse)
cy.get(".nc-view-delete-icon").click({ force: true });
cy.wait(1000);
cy.getActiveModal().find('.ant-btn-dangerous').should('exist').click();
cy.getActiveModal(".nc-modal-view-delete").find('.ant-btn-dangerous').should('exist').click();
cy.toastWait("View deleted successfully");
// confirm if the number of veiw entries is reduced by 1

10
scripts/cypress/integration/common/4f_grid_view_share.js

@ -21,13 +21,13 @@ export const genTest = (apiType, dbType) => {
cy.wait(1000);
// wait, as URL initially will be /undefined
cy.getActiveModal()
cy.getActiveModal(".nc-modal-share-view")
.find(".share-link-box")
.contains("/nc/view/", { timeout: 10000 })
.should("exist");
// copy link text, visit URL
cy.getActiveModal()
cy.getActiveModal(".nc-modal-share-view")
.find(".share-link-box")
.contains("/nc/view/", { timeout: 10000 })
.then(($obj) => {
@ -82,7 +82,7 @@ export const genTest = (apiType, dbType) => {
// create a normal public view
cy.get(`.nc-create-${viewType}-view`).click();
cy.getActiveModal().find("button:contains(Submit)").click();
cy.getActiveModal(".nc-modal-view-create").find("button:contains(Submit)").click();
cy.toastWait("View created successfully");
// store base URL- to re-visit and delete form view later
@ -373,7 +373,7 @@ export const genTest = (apiType, dbType) => {
cy.get(".nc-view-item").its("length").should("eq", 2);
cy.get(".nc-view-delete-icon").eq(0).click({ force: true });
cy.getActiveModal().find(".ant-btn-dangerous").click();
cy.getActiveModal(".nc-modal-view-delete").find(".ant-btn-dangerous").click();
cy.toastWait("View deleted successfully");
// confirm if the number of veiw entries is reduced by 1
@ -424,7 +424,7 @@ export const genTest = (apiType, dbType) => {
// wait for page rendering to complete
cy.get(".nc-grid-row").should("have.length", 10);
mainPage.getCell("Country", 10).rightclick();
cy.getActiveMenu()
cy.getActiveMenu(".nc-dropdown-grid-context-menu")
.find('.ant-dropdown-menu-item:contains("Delete Row")')
.first()
.click();

20
scripts/cypress/integration/common/4f_pg_grid_view_share.js

@ -25,13 +25,13 @@ export const genTest = (apiType, dbType) => {
cy.wait(5000);
// wait, as URL initially will be /undefined
cy.getActiveModal()
cy.getActiveModal(".nc-modal-share-view")
.find(".share-link-box")
.contains("/nc/view/", { timeout: 10000 })
.should("exist");
// copy link text, visit URL
cy.getActiveModal()
cy.getActiveModal(".nc-modal-share-view")
.find(".share-link-box")
.contains("/nc/view/", { timeout: 10000 })
.then(($obj) => {
@ -75,7 +75,7 @@ export const genTest = (apiType, dbType) => {
it(`Create ${viewType.toUpperCase()} view`, () => {
// create a normal public view
cy.get(`.nc-create-${viewType}-view`).click();
cy.getActiveModal().find("button:contains(Submit)").click();
cy.getActiveModal(".nc-modal-view-create").find("button:contains(Submit)").click();
cy.toastWait("View created successfully");
// store base URL- to re-visit and delete form view later
@ -287,16 +287,16 @@ export const genTest = (apiType, dbType) => {
.find("button.mdi-arrow-expand")
.click();
cy.getActiveModal().find("button.mdi-reload").should("exist");
cy.getActiveModal()
cy.getActiveModal(".nc-modal-child-list").find("button.mdi-reload").should("exist");
cy.getActiveModal(".nc-modal-child-list")
.find("button")
.contains("Link to")
.should("not.exist");
cy.getActiveModal()
cy.getActiveModal(".nc-modal-child-list")
.find(".child-card")
.contains("2")
.should("exist");
cy.getActiveModal()
cy.getActiveModal(".nc-modal-child-list")
.find(".child-card")
.find("button")
.should("not.exist");
@ -340,8 +340,8 @@ export const genTest = (apiType, dbType) => {
.find("button.mdi-arrow-expand")
.click();
cy.getActiveModal().find("button.mdi-reload").should("exist");
cy.getActiveModal()
cy.getActiveModal(".nc-modal-child-list").find("button.mdi-reload").should("exist");
cy.getActiveModal(".nc-modal-child-list")
.find("button")
.contains("Link to")
.should("not.exist");
@ -404,7 +404,7 @@ export const genTest = (apiType, dbType) => {
.find(".mdi-checkbox-blank-outline")
.click({ force: true });
mainPage.getCell("Country", 10).rightclick();
cy.getActiveMenu().contains("Delete Selected Row").click();
cy.getActiveMenu(".nc-dropdown-grid-context-menu").contains("Delete Selected Row").click();
// delete column
cy.get(`th:contains('dummy') .mdi-menu-down`)

2
scripts/cypress/integration/common/5b_preview_role.js

@ -35,7 +35,7 @@ export const genTest = (apiType, dbType, roleType) => {
cy.wait(3000);
settingsPage.openProjectMenu();
cy.getActiveMenu().find(`[data-submenu-id="preview-as"]`).should('exist').click()
cy.getActiveMenu(".nc-dropdown-project-menu").find(`[data-submenu-id="preview-as"]`).should('exist').click()
cy.wait(1000)
cy.get('.ant-dropdown-menu-submenu').eq(4).find(`[data-menu-id="editor"]`).should('exist').click()

4
scripts/cypress/integration/common/6d_language_validation.js

@ -24,7 +24,7 @@ export const genTest = (apiType, dbType) => {
after(() => {
cy.get('.nc-menu-accounts').should('exist').click();
cy.getActiveMenu().find('.ant-dropdown-menu-item').eq(1).click();
cy.getActiveMenu('.nc-dropdown-user-accounts-menu').find('.ant-dropdown-menu-item').eq(1).click();
cy.wait(5000);
cy.get('button:contains("SIGN")').should('exist')
@ -39,7 +39,7 @@ export const genTest = (apiType, dbType) => {
// toggle menu as per index
cy.get(".nc-menu-translate").should('exist').last().click();
cy.wait(500);
cy.getActiveMenu().find(".ant-dropdown-menu-item").eq(idx).click();
cy.getActiveMenu(".nc-dropdown-menu-translate").find(".ant-dropdown-menu-item").eq(idx).click();
cy.wait(200);
// basic validations

2
scripts/cypress/integration/common/6e_project_operations.js

@ -22,7 +22,7 @@ export const genTest = (apiType, dbType) => {
.last()
.click();
cy.getActiveModal()
cy.getActiveModal(".nc-modal-project-delete")
.find(".ant-btn-dangerous")
.should("exist")
.click();

6
scripts/cypress/integration/common/6f_attachments.js

@ -41,7 +41,7 @@ export const genTest = (apiType, dbType) => {
// .click({ force: true });
mainPage.getCell("Country", 10).rightclick();
cy.getActiveMenu().contains("Delete Row").click();
cy.getActiveMenu(".nc-dropdown-grid-context-menu").contains("Delete Row").click();
cy.closeTableTab("Country");
});
@ -68,7 +68,7 @@ export const genTest = (apiType, dbType) => {
// create form-view
cy.get(`.nc-create-form-view`).click();
cy.getActiveModal().find("button:contains(Submit)").click();
cy.getActiveModal(".nc-modal-view-create").find("button:contains(Submit)").click();
cy.toastWait("View created successfully");
@ -77,7 +77,7 @@ export const genTest = (apiType, dbType) => {
cy.wait(5000);
// copy link text, visit URL
cy.getActiveModal()
cy.getActiveModal(".nc-modal-share-view")
.find(".share-link-box")
.contains("/nc/form/", { timeout: 10000 })
.should('exist')

4
scripts/cypress/integration/common/6g_base_share.js

@ -77,7 +77,7 @@ export const genTest = (apiType, dbType) => {
// Click on readonly base text
cy.getActiveModal().find(".nc-disable-shared-base").click();
cy.getActiveMenu()
cy.getActiveMenu(".nc-dropdown-shared-base-toggle")
.find(".ant-dropdown-menu-title-content")
.contains("Anyone with the link")
.click();
@ -90,7 +90,7 @@ export const genTest = (apiType, dbType) => {
.click();
// Copy URL
cy.getActiveModal()
cy.getActiveModal(".nc-modal-invite-user-and-share-base")
.find(".nc-url")
.then(($obj) => {
cy.log($obj[0]);

2
scripts/cypress/integration/common/7a_create_project_from_excel.js

@ -106,7 +106,7 @@ export const genTest = (apiType, dbType) => {
cy.get('.nc-add-new-table').should('exist').trigger('mouseover')
cy.get('.nc-import-menu').should('exist').click()
cy.getActiveMenu().find('.ant-dropdown-menu-item').contains('Microsoft Excel').click()
cy.getActiveMenu(".nc-dropdown-import-menu").find('.ant-dropdown-menu-item').contains('Microsoft Excel').click()
cy.get(".nc-input-import").should('exist').find('input').attachFile(filepath);
cy.toastWait("Uploaded file simple.xlsx successfully");

8
scripts/cypress/integration/common/7b_import_from_airtable.js

@ -30,11 +30,11 @@ export const genTest = (apiType, dbType) => {
// trigger import
cy.get('.nc-add-new-table').should('exist').trigger('mouseover')
cy.get('.nc-import-menu').should('exist').click()
cy.getActiveMenu().find('.ant-dropdown-menu-item').contains('Airtable').click()
cy.getActiveMenu(".nc-dropdown-import-menu").find('.ant-dropdown-menu-item').contains('Airtable').click()
cy.getActiveModal().find(".nc-input-api-key").should('exist').clear().type(apiKey)
cy.getActiveModal().find(".nc-input-shared-base").should('exist').clear().type(sharedBase)
cy.getActiveModal().find(".nc-btn-airtable-import").should('exist').click()
cy.getActiveModal(".nc-modal-airtable-import").find(".nc-input-api-key").should('exist').clear().type(apiKey)
cy.getActiveModal(".nc-modal-airtable-import").find(".nc-input-shared-base").should('exist').clear().type(sharedBase)
cy.getActiveModal(".nc-modal-airtable-import").find(".nc-btn-airtable-import").should('exist').click()
// it will take a while for import to finish
// cy.getActiveModal().find(".nc-btn-go-dashboard", {timeout: 180000}).should('exist').click()

16
scripts/cypress/integration/common/8a_webhook.js

@ -7,7 +7,7 @@ let hookPath = "http://localhost:9090/hook";
function createWebhook(hook, test) {
cy.get('.nc-actions-menu-btn').should('exist').click();
cy.getActiveMenu().find('.ant-dropdown-menu-title-content').contains('Webhooks').click()
cy.getActiveMenu(".nc-dropdown-actions-menu").find('.ant-dropdown-menu-title-content').contains('Webhooks').click()
// cy.get(".nc-btn-webhook").should("exist").click();
cy.get(".nc-btn-create-webhook").should("exist").click();
@ -51,7 +51,7 @@ function createWebhook(hook, test) {
function deleteWebhook(index) {
cy.get('.nc-actions-menu-btn').should('exist').click();
cy.getActiveMenu().find('.ant-dropdown-menu-title-content').contains('Webhooks').click()
cy.getActiveMenu(".nc-dropdown-actions-menu").find('.ant-dropdown-menu-title-content').contains('Webhooks').click()
cy.get(".nc-hook-delete-icon").eq(index).click({ force: true });
cy.toastWait("Hook deleted successfully");
@ -60,7 +60,7 @@ function deleteWebhook(index) {
function openWebhook(index) {
cy.get('.nc-actions-menu-btn').should('exist').click();
cy.getActiveMenu().find('.ant-dropdown-menu-title-content').contains('Webhooks').click()
cy.getActiveMenu(".nc-dropdown-actions-menu").find('.ant-dropdown-menu-title-content').contains('Webhooks').click()
cy.get(".nc-hook").eq(index).click({ force: true });
}
@ -161,12 +161,12 @@ function addNewRow(index, cellValue) {
cy.get(".nc-add-new-row-btn").click();
cy.wait(1000);
cy.get(".nc-expand-col-Title").find(".nc-cell > input").first().type(cellValue);
cy.getActiveDrawer()
cy.getActiveDrawer('.nc-drawer-expanded-form')
.find(".ant-btn-primary")
.click();
cy.toastWait("updated successfully");
cy.getActiveDrawer()
cy.getActiveDrawer('.nc-drawer-expanded-form')
.find(".ant-btn")
.contains("Cancel")
.click();
@ -184,14 +184,14 @@ function updateRow(index, cellValue) {
.clear()
.type(cellValue);
cy.getActiveDrawer()
cy.getActiveDrawer('.nc-drawer-expanded-form')
.find("button")
.contains("Save row")
.click({ force: true });
// partial toast message
cy.toastWait("updated successfully");
cy.getActiveDrawer()
cy.getActiveDrawer('.nc-drawer-expanded-form')
.find("button")
.contains("Cancel")
.click({ force: true });
@ -216,7 +216,7 @@ function deleteRow(index) {
.rightclick();
// delete row
cy.getActiveMenu()
cy.getActiveMenu(".nc-dropdown-grid-context-menu")
.find('.ant-dropdown-menu-item:contains("Delete Row")')
.first()
.click({ force: true });

14
scripts/cypress/integration/common/9a_QuickTest.js

@ -40,7 +40,7 @@ let cn = [ "Name", "Notes", "Status", "Tags", "Done", "Date", "Phone",
function openWebhook(index) {
cy.get('.nc-actions-menu-btn').should('exist').click();
cy.getActiveMenu().find('.ant-dropdown-menu-title-content').contains('Webhooks').click()
cy.getActiveMenu(".nc-dropdown-actions-menu").find('.ant-dropdown-menu-title-content').contains('Webhooks').click()
cy.get(".nc-hook").eq(index).click();
}
@ -348,11 +348,11 @@ export const genTest = (apiType, dbType, testMode) => {
cy.wait(2000);
cy.get(".nc-fields-menu-btn").click()
cy.getActiveMenu().find(`[type="checkbox"]`).eq(0).should('be.checked')
cy.getActiveMenu().find(`[type="checkbox"]`).eq(1).should('be.checked')
cy.getActiveMenu().find(`[type="checkbox"]`).eq(2).should('not.be.checked')
cy.getActiveMenu().find(`[type="checkbox"]`).eq(3).should('be.checked')
cy.getActiveMenu().find(`[type="checkbox"]`).eq(4).should('be.checked')
cy.getActiveMenu(".nc-dropdown-fields-menu").find(`[type="checkbox"]`).eq(0).should('be.checked')
cy.getActiveMenu(".nc-dropdown-fields-menu").find(`[type="checkbox"]`).eq(1).should('be.checked')
cy.getActiveMenu(".nc-dropdown-fields-menu").find(`[type="checkbox"]`).eq(2).should('not.be.checked')
cy.getActiveMenu(".nc-dropdown-fields-menu").find(`[type="checkbox"]`).eq(3).should('be.checked')
cy.getActiveMenu(".nc-dropdown-fields-menu").find(`[type="checkbox"]`).eq(4).should('be.checked')
cy.get(".nc-fields-menu-btn").click();
cy.get(".nc-sort-menu-btn").click();
@ -416,7 +416,7 @@ export const genTest = (apiType, dbType, testMode) => {
.last()
.click();
cy.getActiveModal()
cy.getActiveModal(".nc-modal-project-delete")
.find("button")
.contains("Submit")
.should("exist")

34
scripts/cypress/integration/spec/roleValidation.spec.js

@ -13,7 +13,7 @@ export function _advSettings(roleType, mode) {
// open modal
cy.get('.nc-project-menu').should('exist').click()
cy.getActiveMenu().find(`[data-menu-id="language"]`).should('exist')
cy.getActiveMenu(".nc-dropdown-project-menu").find(`[data-menu-id="language"]`).should('exist')
// click again to close modal
cy.get('.nc-project-menu').should('exist').click()
@ -25,11 +25,11 @@ export function _advSettings(roleType, mode) {
// cy.get(".nc-team-settings").should(validationString);
cy.get('.nc-project-menu').should('exist').click()
cy.getActiveMenu().find(`[data-menu-id="preview-as"]`).should(validationString)
cy.getActiveMenu().find(`[data-menu-id="teamAndSettings"]:visible`).should(validationString)
cy.getActiveMenu(".nc-dropdown-project-menu").find(`[data-menu-id="preview-as"]`).should(validationString)
cy.getActiveMenu(".nc-dropdown-project-menu").find(`[data-menu-id="teamAndSettings"]:visible`).should(validationString)
if (true === roles[roleType].validations.advSettings) {
cy.getActiveMenu().find(`[data-menu-id="teamAndSettings"]:visible`).should(validationString).click()
cy.getActiveMenu(".nc-dropdown-project-menu").find(`[data-menu-id="teamAndSettings"]:visible`).should(validationString).click()
cy.get(`[data-menu-id="teamAndAuth"]`).should('exist')
cy.get(`[data-menu-id="appStore"]`).should('exist')
@ -67,8 +67,8 @@ export function _editSchema(roleType, mode) {
cy.get(".ant-dropdown-content:visible").should(validationString);
if(validationString === "exist"){
cy.getActiveMenu().find('[role="menuitem"]').contains("Delete").should("exist");
cy.getActiveMenu().find('[role="menuitem"]').contains("Rename").should("exist");
cy.getActiveMenu(".nc-dropdown-tree-view-context-menu").find('[role="menuitem"]').contains("Delete").should("exist");
cy.getActiveMenu(".nc-dropdown-tree-view-context-menu").find('[role="menuitem"]').contains("Rename").should("exist");
// click on a cell to close table context menu
mainPage.getCell(columnName, 3).click();
@ -83,11 +83,11 @@ export function _editSchema(roleType, mode) {
if(validationString === "exist"){
cy.get('.nc-import-menu').should('exist').click();
cy.getActiveMenu().should('exist')
cy.getActiveMenu().find('.ant-dropdown-menu-item').contains('Airtable')
cy.getActiveMenu().find('.ant-dropdown-menu-item').contains('CSV file')
cy.getActiveMenu().find('.ant-dropdown-menu-item').contains('JSON file')
cy.getActiveMenu().find('.ant-dropdown-menu-item').contains('Microsoft Excel')
cy.getActiveMenu(".nc-dropdown-import-menu").should('exist')
cy.getActiveMenu(".nc-dropdown-import-menu").find('.ant-dropdown-menu-item').contains('Airtable')
cy.getActiveMenu(".nc-dropdown-import-menu").find('.ant-dropdown-menu-item').contains('CSV file')
cy.getActiveMenu(".nc-dropdown-import-menu").find('.ant-dropdown-menu-item').contains('JSON file')
cy.getActiveMenu(".nc-dropdown-import-menu").find('.ant-dropdown-menu-item').contains('Microsoft Excel')
}
}
@ -114,10 +114,10 @@ export function _editData(roleType, mode) {
if (validationString === "exist") {
// right click options will exist (only for 'exist' case)
//
cy.getActiveMenu().contains("Insert New Row").should(validationString);
cy.getActiveMenu().contains("Clear cell").should(validationString);
cy.getActiveMenu().contains("Delete Row").should(validationString);
cy.getActiveMenu().contains("Delete Selected Rows").should(validationString);
cy.getActiveMenu(".nc-dropdown-grid-context-menu").contains("Insert New Row").should(validationString);
cy.getActiveMenu(".nc-dropdown-grid-context-menu").contains("Clear cell").should(validationString);
cy.getActiveMenu(".nc-dropdown-grid-context-menu").contains("Delete Row").should(validationString);
cy.getActiveMenu(".nc-dropdown-grid-context-menu").contains("Delete Selected Rows").should(validationString);
// cy.get("body").type("{esc}");
mainPage.getCell("City", 13).click();
@ -255,10 +255,10 @@ export function _viewMenu(roleType, mode) {
// actions menu (more), only download csv should be visible for non-previlaged users
cy.get(".nc-actions-menu-btn").click();
cy.getActiveMenu()
cy.getActiveMenu(".nc-dropdown-actions-menu")
.find('.ant-dropdown-menu-submenu:visible')
.should("have.length", menuWithSubmenuCount);
cy.getActiveMenu()
cy.getActiveMenu(".nc-dropdown-actions-menu")
.find('.ant-dropdown-menu-item:visible')
.should("have.length", menuWithoutSubmenuCount);
// click again to close menu

29
scripts/cypress/plugins/index.js

@ -77,6 +77,9 @@ module.exports = (on, config) => {
_pgExec(query);
return null;
},
pgExecTest: (query) => {
return _pgExecTest(query);
}
});
let server, port, close
@ -202,6 +205,32 @@ function _pgExec(query) {
});
}
function _pgExecTest(query, retryCount = 60) {
return new Promise((resolve, reject) => {
// open pg client connection
const client = new Client(pg_credentials);
client.connect().catch(() => {
client.end();
});
// query & terminate
client.query(query, (err, res) => {
if (err) {
if (retryCount--)
return setTimeout(() => _pgExecTest(query, retryCount).then(resolve).catch(reject), 2000);
else
reject(err);
}
console.log('==== success ===', res);
resolve(true);
client.end();
});
});
}
/**
* @copyright Copyright (c) 2021, Xgene Cloud Ltd
*

42
scripts/cypress/support/commands.js

@ -141,7 +141,7 @@ Cypress.Commands.add('refreshTableTab', () => {
.first()
.rightclick({ force: true });
cy.getActiveMenu()
cy.getActiveMenu(".nc-dropdown-tree-view-context-menu")
.find('[role="menuitem"]')
.contains('Tables Refresh')
.should('exist')
@ -282,13 +282,16 @@ Cypress.Commands.add('printLocalStorage', () => {
cy.task('log', JSON.stringify(LOCAL_STORAGE_MEMORY, null, 2));
});
Cypress.Commands.add('getActiveModal', () => {
Cypress.Commands.add('getActiveModal', (wrapperSelector) => {
if (wrapperSelector) {
return cy.get(`${wrapperSelector} .ant-modal-content:visible`).last();
}
return cy.get('.ant-modal-content:visible').last();
});
Cypress.Commands.add('getActiveMenu', (overlayClassName) => {
if (overlayClassName) {
return cy.get(`${overlayClassName} .ant-dropdown-content:visible`);
Cypress.Commands.add('getActiveMenu', (overlaySelector) => {
if (overlaySelector) {
return cy.get(`${overlaySelector} .ant-dropdown-content:visible`);
}
return cy.get('.ant-dropdown-content:visible').last();
});
@ -297,15 +300,24 @@ Cypress.Commands.add('getActivePopUp', () => {
return cy.get('.ant-menu-submenu-popup:visible').last();
});
Cypress.Commands.add('getActiveSelection', () => {
Cypress.Commands.add('getActiveSelection', (selector) => {
if (selector) {
return cy.get(`${selector}.ant-select-dropdown:visible`).last();
}
return cy.get('.ant-select-dropdown:visible').last();
});
Cypress.Commands.add('getActiveDrawer', () => {
Cypress.Commands.add('getActiveDrawer', (selector) => {
if (selector) {
return cy.get(`${selector} .ant-drawer-content:visible`).last();
}
return cy.get('.ant-drawer-content:visible').last();
});
Cypress.Commands.add('getActivePicker', () => {
Cypress.Commands.add('getActivePicker', (dropdownSelector) => {
if (dropdownSelector) {
return cy.get(`${dropdownSelector}.ant-drawer-content:visible`).last();
}
return cy.get('.ant-picker-dropdown :visible').last();
});
@ -314,12 +326,12 @@ Cypress.Commands.add('createTable', (name) => {
cy.wait(1000);
cy.get('.nc-add-new-table').should('exist').click();
cy.wait(1000);
cy.getActiveModal().find(`input[type="text"]:visible`)
cy.getActiveModal('.nc-modal-table-create').find(`input[type="text"]:visible`)
.click()
.clear()
.type(name);
// submit button
cy.getActiveModal().find('button.ant-btn-primary:visible').click();
cy.getActiveModal('.nc-modal-table-create').find('button.ant-btn-primary:visible').click();
cy.wait(1000);
cy.get('.xc-row-table.nc-grid').should('exist');
// cy.get('.ant-tabs-tab-active > .ant-tabs-tab-btn').contains(name).should("exist");
@ -330,7 +342,7 @@ Cypress.Commands.add('createTable', (name) => {
Cypress.Commands.add('deleteTable', (name, dbType) => {
cy.get(`.nc-project-tree-tbl-${name}`).should('exist').rightclick();
cy.getActiveMenu().find('[role="menuitem"]').contains('Delete').click();
cy.getActiveMenu(".nc-dropdown-tree-view-context-menu").find('[role="menuitem"]').contains('Delete').click();
cy.getActiveModal().find('button').contains('Yes').click();
cy.toastWait(`Deleted table successfully`);
@ -345,16 +357,16 @@ Cypress.Commands.add('renameTable', (oldName, newName) => {
.rightclick();
// choose rename option from menu
cy.getActiveMenu()
cy.getActiveMenu(".nc-dropdown-tree-view-context-menu")
.find('[role="menuitem"]')
.contains('Rename')
.click({ force: true });
// feed new name
cy.getActiveModal().find('input').clear().type(newName);
cy.getActiveModal(".nc-modal-table-rename").find('input').clear().type(newName);
// submit
cy.getActiveModal().find('button').contains('Submit').click();
cy.getActiveModal(".nc-modal-table-rename").find('button').contains('Submit').click();
cy.toastWait('Table renamed successfully');
@ -483,7 +495,7 @@ Cypress.Commands.add('signOut', () => {
cy.visit(`/`);
cy.get('.nc-project-page-title', { timeout: 30000 }).contains('My Projects').should('be.visible');
cy.get('.nc-menu-accounts', { timeout: 30000 }).should('exist').click();
cy.getActiveMenu().find('.ant-dropdown-menu-item').eq(1).click();
cy.getActiveMenu(".nc-dropdown-user-accounts-menu").find('.ant-dropdown-menu-item').eq(1).click();
cy.wait(5000);
cy.get('button:contains("SIGN")').should('exist');

72
scripts/cypress/support/page_objects/mainPage.js

@ -33,7 +33,7 @@ export class _settingsPage {
// cy.get('.nc-team-settings').should('exist').click()
// cy.get(`[data-menu-id=${menuId}]`).should('exist').click()
cy.get('.nc-project-menu').should('exist').click()
cy.getActiveMenu().find(`[data-menu-id="teamAndSettings"]`).should('exist').click()
cy.getActiveMenu(".nc-dropdown-project-menu").find(`[data-menu-id="teamAndSettings"]`).should('exist').click()
cy.get(`[data-menu-id=${menuId}]`).should('exist').click()
}
@ -89,7 +89,7 @@ export class _mainPage {
navigationDraw(item) {
// open settings tab
cy.get('.nc-project-menu').should('exist').click()
cy.getActiveMenu().find(`[data-menu-id="teamAndSettings"]`).should('exist').click()
cy.getActiveMenu(".nc-dropdown-project-menu").find(`[data-menu-id="teamAndSettings"]`).should('exist').click()
switch (item) {
case this.AUDIT:
@ -120,12 +120,12 @@ export class _mainPage {
// opt-in requested role & submit
// cy.getActiveSelection().contains(roleType).click({force: true});
cy.getActiveSelection().find('.nc-role-option').eq(roleIndex).should('exist').click()
cy.getActiveModal().find("button.ant-btn-primary").click();
cy.getActiveModal(".nc-modal-invite-user-and-share-base").find("button.ant-btn-primary").click();
cy.toastWait("Successfully updated the user details");
// get URL, invoke
cy.getActiveModal()
cy.getActiveModal(".nc-modal-invite-user-and-share-base")
.find(".ant-alert-message")
.then(($obj) => {
linkText = $obj.text().trim();
@ -136,26 +136,26 @@ export class _mainPage {
});
};
addExistingUserToProject = (emailId, role) => {
cy.get('.v-list-item:contains("Team & Auth")').click();
cy.get(`tr:contains(${emailId})`)
.find(".mdi-plus", { timeout: 2000 })
.click();
cy.get(`tr:contains(${emailId})`)
.find(".mdi-pencil-outline", { timeout: 2000 })
.click();
cy.get("label:contains(Select User Role)").click();
// opt-in requested role & submit
//
cy.getActiveMenu().contains(role).click();
cy.get(".nc-invite-or-save-btn").click();
cy.toastWait("Successfully updated the user details");
this.roleURL[role] =
"http://localhost:3000/#/user/authentication/signin";
};
// addExistingUserToProject = (emailId, role) => {
// cy.get('.v-list-item:contains("Team & Auth")').click();
// cy.get(`tr:contains(${emailId})`)
// .find(".mdi-plus", { timeout: 2000 })
// .click();
// cy.get(`tr:contains(${emailId})`)
// .find(".mdi-pencil-outline", { timeout: 2000 })
// .click();
//
// cy.get("label:contains(Select User Role)").click();
//
// // opt-in requested role & submit
// //
// cy.getActiveMenu().contains(role).click();
// cy.get(".nc-invite-or-save-btn").click();
// cy.toastWait("Successfully updated the user details");
//
// this.roleURL[role] =
// "http://localhost:3000/#/user/authentication/signin";
// };
getCell = (columnHeader, cellNumber) => {
return cy.get(
@ -183,7 +183,7 @@ export class _mainPage {
force: true,
});
cy.getActiveMenu().find('input.nc-column-name-input', { timeout: 3000 })
cy.getActiveMenu(".nc-dropdown-grid-add-column").find('input.nc-column-name-input', { timeout: 3000 })
.should('exist')
.clear()
.type(colName);
@ -197,7 +197,7 @@ export class _mainPage {
force: true,
});
cy.getActiveMenu().find('input.nc-column-name-input', { timeout: 3000 })
cy.getActiveMenu(".nc-dropdown-grid-add-column").find('input.nc-column-name-input', { timeout: 3000 })
.should('exist')
.clear()
.type(colName);
@ -265,34 +265,34 @@ export class _mainPage {
shareViewList = () => {
cy.get(".nc-actions-menu-btn").should('exist').click();
return cy.getActiveMenu().find('.ant-dropdown-menu-item').contains('Shared View List');
return cy.getActiveMenu(".nc-dropdown-actions-menu").find('.ant-dropdown-menu-item').contains('Shared View List');
};
downloadCsv = () => {
cy.get(".nc-actions-menu-btn").should('exist').click();
return cy.getActiveMenu().find('.ant-dropdown-menu-item').contains('Download as CSV');
return cy.getActiveMenu(".nc-dropdown-actions-menu").find('.ant-dropdown-menu-item').contains('Download as CSV');
};
downloadExcel = () => {
cy.get(".nc-actions-menu-btn").should('exist').click();
return cy.getActiveMenu().find('.ant-dropdown-menu-item').contains('Download as XLSX');
return cy.getActiveMenu(".nc-dropdown-actions-menu").find('.ant-dropdown-menu-item').contains('Download as XLSX');
};
uploadCsv = () => {
cy.get(".nc-actions-menu-btn").should('exist').click();
return cy.getActiveMenu().find('.ant-dropdown-menu-item').contains('Upload CSV');
return cy.getActiveMenu(".nc-dropdown-actions-menu").find('.ant-dropdown-menu-item').contains('Upload CSV');
};
automations = () => {
cy.get(".nc-actions-menu-btn").should('exist').click();
return cy.getActiveMenu().find('.ant-dropdown-menu-item').contains('Webhooks');
return cy.getActiveMenu(".nc-dropdown-actions-menu").find('.ant-dropdown-menu-item').contains('Webhooks');
};
hideField = (field) => {
cy.get(`th[data-title="${field}"]`).should("be.visible");
cy.get(".nc-fields-menu-btn").click();
cy.wait(500)
cy.getActiveMenu().find(`.nc-fields-list label:contains(${field}):visible`).click();
cy.getActiveMenu(".nc-dropdown-fields-menu").find(`.nc-fields-list label:contains(${field}):visible`).click();
cy.wait(500)
cy.get(".nc-fields-menu-btn").click();
cy.wait(500)
@ -303,7 +303,7 @@ export class _mainPage {
cy.get(`th[data-title="${field}"]`).should("not.exist");
cy.get(".nc-fields-menu-btn").click();
cy.wait(500)
cy.getActiveMenu().find(`.nc-fields-list label:contains(${field}):visible`).click();
cy.getActiveMenu(".nc-dropdown-fields-menu").find(`.nc-fields-list label:contains(${field}):visible`).click();
cy.wait(500)
cy.get(".nc-fields-menu-btn").click();
cy.wait(500)
@ -313,7 +313,7 @@ export class _mainPage {
sortField = (field, criteria) => {
cy.get(".nc-sort-menu-btn").click();
cy.wait(500)
cy.getActiveMenu('.sort-menu-overlay').contains("Add Sort Option").click();
cy.getActiveMenu('.nc-dropdown-sort-menu').contains("Add Sort Option").click();
cy.wait(500)
// cy.get(".nc-sort-field-select div").first().click().type(field);
cy.get(".nc-sort-field-select div").first().click();
@ -411,10 +411,10 @@ export class _mainPage {
if(role === 'commenter' || role === 'viewer') {
cy.get(".nc-actions-menu-btn").click();
cy.getActiveMenu().find('.nc-project-menu-item').contains('Download as CSV').click();
cy.getActiveMenu(".nc-dropdown-actions-menu").find('.nc-project-menu-item').contains('Download as CSV').click();
} else {
cy.get(".nc-actions-menu-btn").click();
cy.getActiveMenu().find('.nc-project-menu-item').contains('Download').click();
cy.getActiveMenu(".nc-dropdown-actions-menu").find('.nc-project-menu-item').contains('Download').click();
cy.wait(1000);
cy.get('.nc-project-menu-item').contains('Download as CSV').should('exist').click();
}

Loading…
Cancel
Save