Browse Source

fix: Fixed PW tests

pull/7280/head
Muhammed Mustafa 10 months ago
parent
commit
065b9f5177
  1. 27
      packages/nc-gui/components/cell/MultiSelect.vue
  2. 35
      packages/nc-gui/components/cell/SingleSelect.vue
  3. 1
      packages/nc-gui/components/smartsheet/Cell.vue
  4. 11
      packages/nc-gui/components/smartsheet/DivDataCell.vue
  5. 2
      packages/nc-gui/components/smartsheet/expanded-form/index.vue
  6. 7
      packages/nc-gui/pages/index/[typeOrId]/form/[viewId]/index/index.vue
  7. 7
      packages/nc-gui/pages/index/[typeOrId]/form/[viewId]/index/survey.vue
  8. 4
      tests/playwright/pages/Dashboard/common/Cell/SelectOptionCell.ts
  9. 3
      tests/playwright/pages/Dashboard/common/Topbar/Share.ts
  10. 1
      tests/playwright/tests/db/views/viewForm.spec.ts

27
packages/nc-gui/components/cell/MultiSelect.vue

@ -53,14 +53,14 @@ const isEditable = inject(EditModeInj, ref(false))
const activeCell = inject(ActiveCellInj, ref(false)) const activeCell = inject(ActiveCellInj, ref(false))
const isForm = inject(IsFormInj, ref(false))
// use both ActiveCellInj or EditModeInj to determine the active state // use both ActiveCellInj or EditModeInj to determine the active state
// since active will be false in case of form view // since active will be false in case of form view
const active = computed(() => activeCell.value || isEditable.value) const active = computed(() => activeCell.value || isEditable.value || isForm.value)
const isPublic = inject(IsPublicInj, ref(false)) const isPublic = inject(IsPublicInj, ref(false))
const isForm = inject(IsFormInj, ref(false))
const isEditColumn = inject(EditColumnInj, ref(false)) const isEditColumn = inject(EditColumnInj, ref(false))
const rowHeight = inject(RowHeightInj, ref(undefined)) const rowHeight = inject(RowHeightInj, ref(undefined))
@ -71,6 +71,8 @@ const aselect = ref<typeof AntSelect>()
const isOpen = ref(false) const isOpen = ref(false)
const isFocusing = ref(false)
const isKanban = inject(IsKanbanInj, ref(false)) const isKanban = inject(IsKanbanInj, ref(false))
const searchVal = ref<string | null>() const searchVal = ref<string | null>()
@ -180,9 +182,7 @@ watch(isOpen, (n, _o) => {
if (!n) searchVal.value = '' if (!n) searchVal.value = ''
if (editAllowed.value) { if (editAllowed.value) {
if (!n) { if (n) {
aselect.value?.$el?.querySelector('input')?.blur()
} else {
aselect.value?.$el?.querySelector('input')?.focus() aselect.value?.$el?.querySelector('input')?.focus()
} }
} }
@ -303,6 +303,9 @@ const cellClickHook = inject(CellClickHookInj, null)
const toggleMenu = () => { const toggleMenu = () => {
if (cellClickHook) return if (cellClickHook) return
if (isFocusing.value) return
isOpen.value = editAllowed.value && !isOpen.value isOpen.value = editAllowed.value && !isOpen.value
} }
@ -351,6 +354,16 @@ const onKeyDown = (e: KeyboardEvent) => {
e.stopPropagation() e.stopPropagation()
} }
const onFocus = () => {
isFocusing.value = true
setTimeout(() => {
isFocusing.value = false
}, 250)
isOpen.value = true
}
</script> </script>
<template> <template>
@ -414,7 +427,7 @@ const onKeyDown = (e: KeyboardEvent) => {
:dropdown-class-name="`nc-dropdown-multi-select-cell !min-w-200px ${isOpen ? 'active' : ''}`" :dropdown-class-name="`nc-dropdown-multi-select-cell !min-w-200px ${isOpen ? 'active' : ''}`"
@search="search" @search="search"
@keydown="onKeyDown" @keydown="onKeyDown"
@focus="isOpen = true" @focus="onFocus"
@blur="isOpen = false" @blur="isOpen = false"
> >
<template #suffixIcon> <template #suffixIcon>

35
packages/nc-gui/components/cell/SingleSelect.vue

@ -47,9 +47,11 @@ const isEditable = inject(EditModeInj, ref(false))
const activeCell = inject(ActiveCellInj, ref(false)) const activeCell = inject(ActiveCellInj, ref(false))
const isForm = inject(IsFormInj, ref(false))
// use both ActiveCellInj or EditModeInj to determine the active state // use both ActiveCellInj or EditModeInj to determine the active state
// since active will be false in case of form view // since active will be false in case of form view
const active = computed(() => activeCell.value || isEditable.value) const active = computed(() => activeCell.value || isEditable.value || isForm.value)
const aselect = ref<typeof AntSelect>() const aselect = ref<typeof AntSelect>()
@ -61,8 +63,6 @@ const isPublic = inject(IsPublicInj, ref(false))
const isEditColumn = inject(EditColumnInj, ref(false)) const isEditColumn = inject(EditColumnInj, ref(false))
const isForm = inject(IsFormInj, ref(false))
const { $api } = useNuxtApp() const { $api } = useNuxtApp()
const searchVal = ref() const searchVal = ref()
@ -77,6 +77,8 @@ const { isPg, isMysql } = useBase()
// temporary until it's add the option to column meta // temporary until it's add the option to column meta
const tempSelectedOptState = ref<string>() const tempSelectedOptState = ref<string>()
const isFocusing = ref(false)
const isNewOptionCreateEnabled = computed(() => !isPublic.value && !disableOptionCreation && isUIAllowed('fieldEdit')) const isNewOptionCreateEnabled = computed(() => !isPublic.value && !disableOptionCreation && isUIAllowed('fieldEdit'))
const options = computed<(SelectOptionType & { value: string })[]>(() => { const options = computed<(SelectOptionType & { value: string })[]>(() => {
@ -97,7 +99,7 @@ const isOptionMissing = computed(() => {
return (options.value ?? []).every((op) => op.title !== searchVal.value) return (options.value ?? []).every((op) => op.title !== searchVal.value)
}) })
const hasEditRoles = computed(() => isUIAllowed('dataEdit')) const hasEditRoles = computed(() => isUIAllowed('dataEdit') || isForm.value)
const editAllowed = computed(() => (hasEditRoles.value || isForm.value) && active.value) const editAllowed = computed(() => (hasEditRoles.value || isForm.value) && active.value)
@ -243,6 +245,9 @@ const toggleMenu = (e: Event) => {
return e.stopPropagation() return e.stopPropagation()
} }
if (cellClickHook) return if (cellClickHook) return
if (isFocusing.value) return
isOpen.value = editAllowed.value && !isOpen.value isOpen.value = editAllowed.value && !isOpen.value
} }
@ -268,21 +273,19 @@ const selectedOpt = computed(() => {
return options.value.find((o) => o.value === vModel.value || o.value === vModel.value?.trim()) return options.value.find((o) => o.value === vModel.value || o.value === vModel.value?.trim())
}) })
watch(aselect, () => { const onFocus = () => {
if (aselect.value) { isFocusing.value = true
const inputDom = aselect.value.$el.querySelector('.ant-select-selection-search > input')
// Add tabindex="-1" to input element setTimeout(() => {
if (inputDom) { isFocusing.value = false
inputDom.setAttribute('tabindex', '-1') }, 250)
}
} isOpen.value = true
}) }
</script> </script>
<template> <template>
<div <div
tabindex="0"
class="h-full w-full flex items-center nc-single-select focus:outline-transparent" class="h-full w-full flex items-center nc-single-select focus:outline-transparent"
:class="{ 'read-only': readOnly }" :class="{ 'read-only': readOnly }"
@click="toggleMenu" @click="toggleMenu"
@ -329,12 +332,14 @@ watch(aselect, () => {
:bordered="false" :bordered="false"
:open="isOpen && editAllowed" :open="isOpen && editAllowed"
:disabled="readOnly || !editAllowed" :disabled="readOnly || !editAllowed"
:show-arrow="hasEditRoles && !readOnly && active && vModel === null" :show-search="!isMobileMode && isOpen && active"
:show-arrow="hasEditRoles && !readOnly && active && (vModel === null || vModel === undefined)"
:dropdown-class-name="`nc-dropdown-single-select-cell ${isOpen && active ? 'active' : ''}`" :dropdown-class-name="`nc-dropdown-single-select-cell ${isOpen && active ? 'active' : ''}`"
@select="onSelect" @select="onSelect"
@keydown="onKeydown($event)" @keydown="onKeydown($event)"
@search="search" @search="search"
@blur="isOpen = false" @blur="isOpen = false"
@focus="onFocus"
> >
<a-select-option <a-select-option
v-for="op of options" v-for="op of options"

1
packages/nc-gui/components/smartsheet/Cell.vue

@ -205,7 +205,6 @@ onUnmounted(() => {
'h-10': isForm && !isSurveyForm && !isAttachment(column) && !props.virtual, 'h-10': isForm && !isSurveyForm && !isAttachment(column) && !props.virtual,
'nc-grid-numeric-cell-left': (isForm && isNumericField && isExpandedFormOpen) || isEditColumnMenu, 'nc-grid-numeric-cell-left': (isForm && isNumericField && isExpandedFormOpen) || isEditColumnMenu,
'!min-h-30 resize-y': isTextArea(column) && (isForm || isSurveyForm), '!min-h-30 resize-y': isTextArea(column) && (isForm || isSurveyForm),
'!border-2 !border-brand-500': props.editEnabled && (isSurveyForm || isForm) && !isDrawerExist(),
}, },
]" ]"
@keydown.enter.exact="navigate(NavigateDir.NEXT, $event)" @keydown.enter.exact="navigate(NavigateDir.NEXT, $event)"

11
packages/nc-gui/components/smartsheet/DivDataCell.vue

@ -7,7 +7,16 @@ provide(CurrentCellInj, el)
</script> </script>
<template> <template>
<div ref="el" class="select-none"> <div ref="el" class="select-none nc-data-cell">
<slot /> <slot />
</div> </div>
</template> </template>
<style lang="scss" scoped>
.nc-data-cell:focus-within {
@apply !border-1 !border-brand-500 !rounded-lg !shadow-none !ring-0;
}
.nc-data-cell {
@apply border-1 border-gray-200 overflow-hidden rounded-lg;
}
</style>

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

@ -684,7 +684,7 @@ export default {
<SmartsheetDivDataCell <SmartsheetDivDataCell
v-if="col.title" v-if="col.title"
:ref="i ? null : (el: any) => (cellWrapperEl = el)" :ref="i ? null : (el: any) => (cellWrapperEl = el)"
class="nc-data-cell bg-white rounded-lg w-80 xs:w-full border-1 border-gray-200 overflow-hidden px-1 sm:min-h-[35px] xs:min-h-13 flex items-center relative" class="bg-white w-80 xs:w-full px-1 sm:min-h-[35px] xs:min-h-13 flex items-center relative"
:class="{ :class="{
'!bg-gray-50 !px-0 !select-text': isReadOnlyVirtualCell(col), '!bg-gray-50 !px-0 !select-text': isReadOnlyVirtualCell(col),
}" }"

7
packages/nc-gui/pages/index/[typeOrId]/form/[viewId]/index/index.vue

@ -27,8 +27,6 @@ const scannerIsReady = ref(false)
const showCodeScannerOverlay = ref(false) const showCodeScannerOverlay = ref(false)
const editEnabled = ref<boolean[]>([])
const onLoaded = async () => { const onLoaded = async () => {
scannerIsReady.value = true scannerIsReady.value = true
} }
@ -168,10 +166,7 @@ const onDecode = async (scannedCodeValue: string) => {
:data-testid="`nc-form-input-cell-${field.label || field.title}`" :data-testid="`nc-form-input-cell-${field.label || field.title}`"
:class="`nc-form-input-${field.title?.replaceAll(' ', '')}`" :class="`nc-form-input-${field.title?.replaceAll(' ', '')}`"
:column="field" :column="field"
:edit-enabled="editEnabled[index]" edit-enabled
@click="editEnabled[index] = true"
@cancel="editEnabled[index] = false"
@update:edit-enabled="editEnabled[index] = $event"
/> />
<a-button <a-button
v-if="field.enable_scanner" v-if="field.enable_scanner"

7
packages/nc-gui/pages/index/[typeOrId]/form/[viewId]/index/survey.vue

@ -47,8 +47,6 @@ const animationTarget = ref<AnimationTarget>(AnimationTarget.ArrowRight)
const isAnimating = ref(false) const isAnimating = ref(false)
const editEnabled = ref<boolean[]>([])
const el = ref<HTMLDivElement>() const el = ref<HTMLDivElement>()
provide(DropZoneRef, el) provide(DropZoneRef, el)
@ -299,10 +297,7 @@ onMounted(() => {
class="nc-input h-auto" class="nc-input h-auto"
:data-testid="`nc-survey-form__input-${field.title.replaceAll(' ', '')}`" :data-testid="`nc-survey-form__input-${field.title.replaceAll(' ', '')}`"
:column="field" :column="field"
:edit-enabled="editEnabled[index]" edit-enabled
@click="editEnabled[index] = true"
@cancel="editEnabled[index] = false"
@update:edit-enabled="editEnabled[index] = $event"
/> />
<div class="flex flex-col gap-2 text-slate-500 dark:text-slate-300 text-[0.75rem] my-2 px-1"> <div class="flex flex-col gap-2 text-slate-500 dark:text-slate-300 text-[0.75rem] my-2 px-1">

4
tests/playwright/pages/Dashboard/common/Cell/SelectOptionCell.ts

@ -19,11 +19,13 @@ export class SelectOptionCellPageObject extends BasePage {
columnHeader, columnHeader,
option, option,
multiSelect, multiSelect,
ignoreDblClick,
}: { }: {
index: number; index: number;
columnHeader: string; columnHeader: string;
option: string; option: string;
multiSelect?: boolean; multiSelect?: boolean;
ignoreDblClick?: boolean;
}) { }) {
const selectCell = this.get({ index, columnHeader }); const selectCell = this.get({ index, columnHeader });
@ -32,7 +34,7 @@ export class SelectOptionCellPageObject extends BasePage {
!(await selectCell.getAttribute('class')).includes('active') && !(await selectCell.getAttribute('class')).includes('active') &&
(await selectCell.locator('.nc-selected-option').count()) === 0 (await selectCell.locator('.nc-selected-option').count()) === 0
) { ) {
await selectCell.click(); if (!ignoreDblClick) await selectCell.click();
} }
await selectCell.click(); await selectCell.click();

3
tests/playwright/pages/Dashboard/common/Topbar/Share.ts

@ -1,6 +1,6 @@
import BasePage from '../../../Base'; import BasePage from '../../../Base';
import { TopbarPage } from '../Topbar'; import { TopbarPage } from '../Topbar';
import { Locator } from '@playwright/test'; import { expect, Locator } from '@playwright/test';
export class TopbarSharePage extends BasePage { export class TopbarSharePage extends BasePage {
readonly topbar: TopbarPage; readonly topbar: TopbarPage;
@ -25,6 +25,7 @@ export class TopbarSharePage extends BasePage {
} }
async clickShareViewPublicAccess() { async clickShareViewPublicAccess() {
await expect(this.get().locator(`[data-testid="share-view-toggle"]`)).toHaveCount(1);
await this.get().locator(`[data-testid="share-view-toggle"]`).click(); await this.get().locator(`[data-testid="share-view-toggle"]`).click();
} }

1
tests/playwright/tests/db/views/viewForm.spec.ts

@ -486,6 +486,7 @@ test.describe('Form view', () => {
columnHeader: 'MultiSelect', columnHeader: 'MultiSelect',
option: 'jan', option: 'jan',
multiSelect: true, multiSelect: true,
ignoreDblClick: true,
}; };
await sharedForm.cell.selectOption.select({ ...multiSelectParams, option: 'jan' }); await sharedForm.cell.selectOption.select({ ...multiSelectParams, option: 'jan' });
await sharedForm.cell.selectOption.select({ ...multiSelectParams, option: 'feb' }); await sharedForm.cell.selectOption.select({ ...multiSelectParams, option: 'feb' });

Loading…
Cancel
Save