Browse Source

Merge pull request #7625 from nocodb/nc-cmd-l

fix(nc-gui): cmd l fixes
pull/7652/head
Raju Udava 9 months ago committed by GitHub
parent
commit
070a59e270
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 1
      packages/nc-gui/app.vue
  2. 9
      packages/nc-gui/assets/nc-icons/project-gray.svg
  3. 220
      packages/nc-gui/components/cmd-l/index.vue
  4. 6
      packages/nc-gui/components/dlg/TableRename.vue
  5. 2
      packages/nc-gui/store/views.ts
  6. 2
      packages/nc-gui/utils/iconUtils.ts
  7. 2
      tests/playwright/pages/Dashboard/Command/CmdJPage.ts
  8. 3
      tests/playwright/pages/Dashboard/Command/CmdKPage.ts
  9. 9
      tests/playwright/pages/Dashboard/Command/CmdLPage.ts
  10. 98
      tests/playwright/tests/db/features/command.spec.ts

1
packages/nc-gui/app.vue

@ -1,6 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { applyNonSelectable, computed, isEeUI, isMac, useCommandPalette, useRouter, useTheme } from '#imports' import { applyNonSelectable, computed, isEeUI, isMac, useCommandPalette, useRouter, useTheme } from '#imports'
import type { CommandPaletteType } from '~/lib' import type { CommandPaletteType } from '~/lib'
const router = useRouter() const router = useRouter()
const route = router.currentRoute const route = router.currentRoute

9
packages/nc-gui/assets/nc-icons/project-gray.svg

@ -0,0 +1,9 @@
<svg width="16" height="17" viewBox="0 0 16 17" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.99294 15.3098L14.548 12.7802C14.8177 12.6574 14.9569 12.4978 14.9659 12.3369H1C1.00896 12.4978 1.14826 12.6574 1.4179 12.7802L6.97294 15.3098C7.53075 15.5637 8.43514 15.5637 8.99294 15.3098Z" fill="#5F5F5F"/>
<path d="M14.9999 9.77881H1.00513V12.3366H14.9999V9.77881Z" fill="#5F5F5F"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.99294 12.7517L14.548 10.2221C14.8177 10.0993 14.9569 9.93968 14.9659 9.77881H1C1.00896 9.93968 1.14826 10.0993 1.4179 10.2221L6.97294 12.7517C7.53075 13.0056 8.43514 13.0056 8.99294 12.7517Z" fill="#5F5F5F"/>
<path d="M14.9999 7.22119H1.00513V9.77897H14.9999V7.22119Z" fill="#5F5F5F"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.99294 11.4729L14.548 8.94332C14.8177 8.82054 14.9569 8.66088 14.9659 8.5H1C1.00896 8.66088 1.14826 8.82054 1.4179 8.94332L6.97294 11.4729C7.53075 11.7269 8.43514 11.7269 8.99294 11.4729Z" fill="#C4C4C4"/>
<path d="M14.9997 4.66309H1.00488V8.50309H14.9997V4.66309Z" fill="#C4C4C4"/>
<path d="M14.5484 5.13991L8.99337 7.66947C8.43561 7.92348 7.53121 7.92348 6.9734 7.66947L1.41836 5.13991C0.860546 4.8859 0.860546 4.47408 1.41836 4.22007L6.9734 1.69051C7.53121 1.4365 8.43561 1.4365 8.99337 1.69051L14.5484 4.22007C15.1063 4.47408 15.1063 4.8859 14.5484 5.13991Z" fill="#C4C4C4"/>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

220
packages/nc-gui/components/cmd-l/index.vue

@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { onKeyUp, useDebounceFn, useMagicKeys, useVModel, whenever } from '@vueuse/core' import { onKeyUp, useDebounceFn, useVModel } from '@vueuse/core'
import { onClickOutside } from '#imports' import { iconMap, onClickOutside } from '#imports'
import type { CommandPaletteType } from '~/lib' import type { CommandPaletteType } from '~/lib'
const props = defineProps<{ const props = defineProps<{
@ -12,8 +12,12 @@ const emits = defineEmits(['update:open'])
const vOpen = useVModel(props, 'open', emits) const vOpen = useVModel(props, 'open', emits)
const search = ref('')
const modalEl = ref<HTMLElement>() const modalEl = ref<HTMLElement>()
const cmdInputEl = ref<HTMLInputElement>()
const { user } = useGlobal() const { user } = useGlobal()
const viewStore = useViewsStore() const viewStore = useViewsStore()
@ -22,14 +26,26 @@ const { recentViews, activeView } = storeToRefs(viewStore)
const selected: Ref<string> = ref('') const selected: Ref<string> = ref('')
const newView: Ref< const newView = ref<
| { | {
viewId: string | null viewId: string | null
tableId: string tableId: string
baseId: string baseId: string
} }
| undefined | undefined
> = ref() >()
const filteredViews = computed(() => {
if (!recentViews.value) return []
const filtered = recentViews.value.filter((v) => {
if (search.value === '') return true
return v.viewName.toLowerCase().includes(search.value.toLowerCase())
})
if (filtered[0]) {
selected.value = filtered[0]?.tableID + filtered[0]?.viewName
}
return filtered
})
const changeView = useDebounceFn( const changeView = useDebounceFn(
async ({ viewId, tableId, baseId }: { viewId: string | null; tableId: string; baseId: string }) => { async ({ viewId, tableId, baseId }: { viewId: string | null; tableId: string; baseId: string }) => {
@ -39,36 +55,26 @@ const changeView = useDebounceFn(
200, 200,
) )
const keys = useMagicKeys()
const { current } = keys
onKeyUp('Enter', async () => { onKeyUp('Enter', async () => {
if (vOpen.value && newView.value) { if (vOpen.value && newView.value) {
search.value = ''
await changeView({ viewId: newView.value.viewId, tableId: newView.value.tableId, baseId: newView.value.baseId }) await changeView({ viewId: newView.value.viewId, tableId: newView.value.tableId, baseId: newView.value.baseId })
} }
}) })
function scrollToTarget() { function scrollToTarget() {
const element = document.querySelector('.cmdk-action.selected') const element = document.querySelector('.cmdk-action.selected')
const headerOffset = 45 element?.scrollIntoView()
const elementPosition = element?.getBoundingClientRect().top
const offsetPosition = elementPosition! + window.pageYOffset - headerOffset
window.scrollTo({
top: offsetPosition,
behavior: 'smooth',
})
} }
const moveUp = () => { const moveUp = () => {
if (!recentViews.value.length) return if (!filteredViews.value.length) return
const index = recentViews.value.findIndex((v) => v.tableID + v.viewName === selected.value) const index = filteredViews.value.findIndex((v) => v.tableID + v.viewName === selected.value)
if (index === 0) { if (index === 0) {
selected.value = selected.value =
recentViews.value[recentViews.value.length - 1].tableID + recentViews.value[recentViews.value.length - 1].viewName filteredViews.value[filteredViews.value.length - 1].tableID + filteredViews.value[filteredViews.value.length - 1].viewName
const cmdOption = recentViews.value[recentViews.value.length - 1] const cmdOption = filteredViews.value[filteredViews.value.length - 1]
newView.value = { newView.value = {
viewId: cmdOption.viewId ?? null, viewId: cmdOption.viewId ?? null,
tableId: cmdOption.tableID, tableId: cmdOption.tableID,
@ -76,25 +82,25 @@ const moveUp = () => {
} }
document.querySelector('.actions')?.scrollTo({ top: 99999, behavior: 'smooth' }) document.querySelector('.actions')?.scrollTo({ top: 99999, behavior: 'smooth' })
} else { } else {
selected.value = recentViews.value[index - 1].tableID + recentViews.value[index - 1].viewName selected.value = filteredViews.value[index - 1].tableID + filteredViews.value[index - 1].viewName
const cmdOption = recentViews.value[index - 1] const cmdOption = filteredViews.value[index - 1]
scrollToTarget()
newView.value = { newView.value = {
viewId: cmdOption.viewId ?? null, viewId: cmdOption.viewId ?? null,
tableId: cmdOption.tableID, tableId: cmdOption.tableID,
baseId: cmdOption.baseId, baseId: cmdOption.baseId,
} }
nextTick(() => scrollToTarget())
} }
} }
const moveDown = () => { const moveDown = () => {
if (!recentViews.value.length) return if (!filteredViews.value.length) return
const index = recentViews.value.findIndex((v) => v.tableID + v.viewName === selected.value) const index = filteredViews.value.findIndex((v) => v.tableID + v.viewName === selected.value)
if (index === recentViews.value.length - 1) { if (index === filteredViews.value.length - 1) {
selected.value = recentViews.value[0].tableID + recentViews.value[0].viewName selected.value = filteredViews.value[0].tableID + filteredViews.value[0].viewName
const cmdOption = recentViews.value[0] const cmdOption = filteredViews.value[0]
newView.value = { newView.value = {
viewId: cmdOption.viewId ?? null, viewId: cmdOption.viewId ?? null,
tableId: cmdOption.tableID, tableId: cmdOption.tableID,
@ -102,91 +108,74 @@ const moveDown = () => {
} }
document.querySelector('.actions')?.scrollTo({ top: 0, behavior: 'smooth' }) document.querySelector('.actions')?.scrollTo({ top: 0, behavior: 'smooth' })
} else { } else {
selected.value = recentViews.value[index + 1].tableID + recentViews.value[index + 1].viewName selected.value = filteredViews.value[index + 1].tableID + filteredViews.value[index + 1].viewName
const cmdOption = recentViews.value[index + 1] const cmdOption = filteredViews.value[index + 1]
scrollToTarget()
newView.value = { newView.value = {
viewId: cmdOption.viewId ?? null, viewId: cmdOption.viewId ?? null,
tableId: cmdOption.tableID, tableId: cmdOption.tableID,
baseId: cmdOption.baseId, baseId: cmdOption.baseId,
} }
nextTick(() => scrollToTarget())
} }
} }
whenever(keys['Ctrl+Shift+L'], async () => { const hide = () => {
if (!user.value) return vOpen.value = false
vOpen.value = true search.value = ''
moveUp() }
})
whenever(keys['Meta+Shift+L'], async () => { onClickOutside(modalEl, () => {
if (!user.value) return hide()
vOpen.value = true
moveUp()
}) })
whenever(keys.ctrl_l, async () => { useEventListener('keydown', (e: KeyboardEvent) => {
if (e.key === 'Escape') {
hide()
} else if (e.key === 'Enter') {
if (newView.value) {
changeView({ viewId: newView.value.viewId, tableId: newView.value.tableId, baseId: newView.value.baseId })
}
} else if (e.key === 'ArrowUp') {
if (!vOpen.value) return
e.preventDefault()
moveUp()
} else if (e.key === 'ArrowDown') {
if (!vOpen.value) return
e.preventDefault()
moveDown()
} else if ((e.metaKey || e.ctrlKey) && e.shiftKey && e.key.toLowerCase() === 'l') {
if (!user.value) return if (!user.value) return
if (current.has('shift')) return if (!vOpen.value) {
vOpen.value = true vOpen.value = true
moveDown() } else {
}) moveUp()
}
whenever(keys.meta_l, async () => { } else if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === 'l') {
if (!user.value) return if (!user.value) return
if (current.has('shift')) return if (!vOpen.value) {
vOpen.value = true vOpen.value = true
moveDown() } else moveDown()
}) } else if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === 'k') {
hide()
whenever(keys.arrowup, () => { } else if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === 'j') {
if (vOpen.value) moveUp() hide()
}) } else if (vOpen.value) {
cmdInputEl.value?.focus()
whenever(keys.arrowdown, () => { }
if (vOpen.value) moveDown()
})
const hide = () => {
vOpen.value = false
}
whenever(keys.Escape, () => {
if (vOpen.value) hide()
})
whenever(keys.ctrl_k, () => {
if (vOpen.value) hide()
})
whenever(keys.meta_k, () => {
if (vOpen.value) hide()
})
whenever(keys.ctrl_j, () => {
if (vOpen.value) hide()
})
whenever(keys.meta_j, () => {
if (vOpen.value) hide()
})
onClickOutside(modalEl, () => {
if (vOpen.value) hide()
}) })
onMounted(() => { onMounted(() => {
document.querySelector('.cmdOpt-list')?.focus() document.querySelector('.cmdOpt-list')?.focus()
if (!activeView.value) return if (!activeView.value || !filteredViews.value.length) return
const index = recentViews.value.findIndex( const index = filteredViews.value.findIndex(
(v) => v.viewName === activeView.value?.name && v.tableID === activeView.value?.tableId, (v) => v.viewName === activeView.value?.title && v.tableID === activeView.value?.fk_model_id,
) )
if (index + 1 > recentViews.value.length) { if (index + 1 > filteredViews.value.length) {
selected.value = recentViews.value[0].tableID + recentViews.value[0].viewName selected.value = filteredViews.value[0].tableID + filteredViews.value[0].viewName
} else { } else {
selected.value = recentViews.value[index + 1].tableID + recentViews.value[index + 1].viewName if (!filteredViews.value[index + 1]) return
selected.value = filteredViews.value[index + 1].tableID + filteredViews.value[index + 1].viewName
} }
}) })
</script> </script>
@ -194,45 +183,64 @@ onMounted(() => {
<template> <template>
<div v-if="vOpen" class="cmdk-modal cmdl-modal" :class="{ 'cmdk-modal-active cmdl-modal-active': vOpen }"> <div v-if="vOpen" class="cmdk-modal cmdl-modal" :class="{ 'cmdk-modal-active cmdl-modal-active': vOpen }">
<div ref="modalEl" class="cmdk-modal-content cmdl-modal-content relative h-[25.25rem]"> <div ref="modalEl" class="cmdk-modal-content cmdl-modal-content relative h-[25.25rem]">
<div class="cmdk-input-wrapper">
<GeneralIcon class="h-4 w-4 text-gray-500" icon="search" />
<input ref="cmdInputEl" v-model="search" class="cmdk-input" placeholder="Search" type="text" />
</div>
<div class="flex items-center bg-white w-full z-[50]"> <div class="flex items-center bg-white w-full z-[50]">
<div class="text-sm p-4 text-gray-500">Recent Views</div> <div class="text-sm px-4 py-2 text-gray-500">Recent Views</div>
</div> </div>
<div class="flex flex-col shrink grow overflow-hidden shadow-[rgb(0_0_0_/_50%)_0px_16px_70px] max-w-[650px] p-0"> <div class="flex flex-col shrink grow overflow-hidden shadow-[rgb(0_0_0_/_50%)_0px_16px_70px] max-w-[650px] p-0">
<div class="scroll-smooth actions overflow-auto nc-scrollbar-md relative m-0 px-0 py-2"> <div class="scroll-smooth actions overflow-auto nc-scrollbar-md mb-10 relative mx-0 px-0 py-2">
<div v-if="recentViews.length < 1" class="flex flex-col p-4 items-start justify-center text-md">No recent views</div> <div v-if="filteredViews.length < 1" class="flex flex-col p-4 items-start justify-center text-md">No recent views</div>
<div v-else class="flex mb-10 flex-col cmdOpt-list w-full"> <div v-else class="flex flex-col cmdOpt-list w-full">
<div <div
v-for="cmdOption of recentViews" v-for="cmdOption of filteredViews"
:key="cmdOption.tableID + cmdOption.viewName" :key="cmdOption.tableID + cmdOption.viewName"
v-e="['a:cmdL:changeView']" v-e="['a:cmdL:changeView']"
:class="{ :class="{
selected: selected === cmdOption.tableID + cmdOption.viewName, selected: selected === cmdOption.tableID + cmdOption.viewName,
}" }"
class="cmdk-action" class="cmdk-action"
@click="changeView({ viewId: cmdOption.viewId, tableId: cmdOption.tableID, baseId: cmdOption.baseId })" @click="changeView({ viewId: cmdOption.viewId!, tableId: cmdOption.tableID, baseId: cmdOption.baseId })"
> >
<div class="cmdk-action-content !flex w-full"> <div class="cmdk-action-content">
<div class="flex gap-2 w-full flex-grow-1 items-center"> <div class="flex w-1/2 items-center">
<GeneralViewIcon :meta="{ type: cmdOption.viewType }" /> <div class="flex gap-2">
<GeneralViewIcon :meta="{ type: cmdOption.viewType }" class="mt-0.5" />
<a-tooltip overlay-class-name="!px-2 !py-1 !rounded-lg"> <a-tooltip overlay-class-name="!px-2 !py-1 !rounded-lg">
<template #title> <template #title>
{{ cmdOption.isDefault ? $t('title.defaultView') : cmdOption.viewName }} {{ cmdOption.viewName }}
</template> </template>
<span class="max-w- truncate capitalize"> <span class="truncate max-w-56 capitalize">
{{ cmdOption.isDefault ? $t('title.defaultView') : cmdOption.viewName }} {{ cmdOption.viewName }}
</span> </span>
</a-tooltip> </a-tooltip>
</div> </div>
<div class="flex gap-2 bg-gray-100 px-2 py-1 rounded-md text-gray-600 items-center"> </div>
<component :is="iconMap.project" class="w-4 h-4 text-transparent" /> <div class="flex w-1/2 justify-end text-gray-600">
<div class="flex gap-2 px-2 py-1 rounded-md items-center">
<component :is="iconMap.projectGray" class="w-3 h-3 text-transparent" />
<a-tooltip overlay-class-name="!px-2 !py-1 !rounded-lg"> <a-tooltip overlay-class-name="!px-2 !py-1 !rounded-lg">
<template #title> <template #title>
{{ cmdOption.baseName }} {{ cmdOption.baseName }}
</template> </template>
<span class="max-w-32 truncate capitalize"> <span class="max-w-32 text-xs truncate capitalize">
{{ cmdOption.baseName }} {{ cmdOption.baseName }}
</span> </span>
</a-tooltip> </a-tooltip>
<span class="text-bold"> / </span>
<component :is="iconMap.table" class="w-3 h-3 text-transparent" />
<a-tooltip overlay-class-name="!px-2 !py-1 !rounded-lg">
<template #title>
{{ cmdOption.tableName }}
</template>
<span class="max-w-28 text-xs truncate capitalize">
{{ cmdOption.tableName }}
</span>
</a-tooltip>
</div>
</div> </div>
</div> </div>
</div> </div>

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

@ -162,8 +162,10 @@ const renameTable = async (undo = false, disableTitleDiffCheck?: boolean | undef
// update recent views if default view is renamed // update recent views if default view is renamed
allRecentViews.value = allRecentViews.value.map((v) => { allRecentViews.value = allRecentViews.value.map((v) => {
if (v.tableID === tableMeta.id && v.isDefault) { if (v.tableID === tableMeta.id) {
v.viewName = formState.title if (v.isDefault) v.viewName = formState.title
v.tableName = formState.title
} }
return v return v
}) })

2
packages/nc-gui/store/views.ts

@ -11,6 +11,7 @@ export const useViewsStore = defineStore('viewsStore', () => {
tableID: string tableID: string
isDefault: boolean isDefault: boolean
baseName: string baseName: string
tableName: string
workspaceId: string workspaceId: string
baseId: string baseId: string
} }
@ -293,6 +294,7 @@ export const useViewsStore = defineStore('viewsStore', () => {
viewName: view.is_default ? (tableName as string) : view.title, viewName: view.is_default ? (tableName as string) : view.title,
viewType: view.type, viewType: view.type,
workspaceId: activeWorkspaceId.value, workspaceId: activeWorkspaceId.value,
tableName: tableName as string,
baseName: baseName as string, baseName: baseName as string,
}, },
...allRecentViews.value.filter((f) => f.viewId !== view.id || f.tableID !== view.fk_model_id), ...allRecentViews.value.filter((f) => f.viewId !== view.id || f.tableID !== view.fk_model_id),

2
packages/nc-gui/utils/iconUtils.ts

@ -120,6 +120,7 @@ import NcArrowUp from '~icons/nc-icons/arrow-up'
import NcArrowDown from '~icons/nc-icons/arrow-down' import NcArrowDown from '~icons/nc-icons/arrow-down'
import NcUpload from '~icons/nc-icons/upload' import NcUpload from '~icons/nc-icons/upload'
import NcDownload from '~icons/nc-icons/download' import NcDownload from '~icons/nc-icons/download'
import NcProjectGray from '~icons/nc-icons/project-gray'
// keep it for reference // keep it for reference
// todo: remove it after all icons are migrated // todo: remove it after all icons are migrated
@ -269,6 +270,7 @@ import NcDownload from '~icons/nc-icons/download'
} as const */ } as const */
export const iconMap = { export const iconMap = {
projectGray: NcProjectGray,
sort: Sort, sort: Sort,
group: Group, group: Group,
filter: Filter, filter: Filter,

2
tests/playwright/pages/Dashboard/Command/CmdJPage.ts

@ -14,7 +14,7 @@ export class CmdJ extends BasePage {
} }
async openCmdJ() { async openCmdJ() {
await this.dashboardPage.rootPage.keyboard.press(this.isMacOs() ? 'Meta+J' : 'Control+J'); await this.dashboardPage.rootPage.keyboard.press((await this.isMacOs()) ? 'Meta+J' : 'Control+J');
// await this.dashboardPage.rootPage.waitForSelector('.DocSearch-Input'); // await this.dashboardPage.rootPage.waitForSelector('.DocSearch-Input');
} }

3
tests/playwright/pages/Dashboard/Command/CmdKPage.ts

@ -14,8 +14,7 @@ export class CmdK extends BasePage {
} }
async openCmdK() { async openCmdK() {
await this.dashboardPage.rootPage.keyboard.press(this.isMacOs() ? 'Meta+K' : 'Control+K'); await this.dashboardPage.rootPage.keyboard.press((await this.isMacOs()) ? 'Meta+K' : 'Control+K');
// await this.dashboardPage.rootPage.waitForSelector('.DocSearch-Input');
} }
async searchText(text: string) { async searchText(text: string) {

9
tests/playwright/pages/Dashboard/Command/CmdLPage.ts

@ -1,5 +1,6 @@
import BasePage from '../../Base'; import BasePage from '../../Base';
import { DashboardPage } from '..'; import { DashboardPage } from '..';
import { expect } from '@playwright/test';
export class CmdL extends BasePage { export class CmdL extends BasePage {
readonly dashboardPage: DashboardPage; readonly dashboardPage: DashboardPage;
@ -14,17 +15,15 @@ export class CmdL extends BasePage {
} }
async openCmdL() { async openCmdL() {
await this.dashboardPage.rootPage.keyboard.press(this.isMacOs() ? 'Meta+L' : 'Control+L'); await this.dashboardPage.rootPage.keyboard.press((await this.isMacOs()) ? 'Meta+l' : 'Control+l');
} }
async isCmdLVisible() { async isCmdLVisible() {
const isVisible = this.get(); await expect(this.get()).toBeVisible();
return await isVisible.count();
} }
async isCmdLNotVisible() { async isCmdLNotVisible() {
const isNotVisible = this.get(); await expect(this.get()).toBeHidden();
return await isNotVisible.count();
} }
async moveDown() { async moveDown() {

98
tests/playwright/tests/db/features/command.spec.ts

@ -0,0 +1,98 @@
import { expect, test } from '@playwright/test';
import { DashboardPage } from '../../../pages/Dashboard';
import setup, { unsetup } from '../../../setup';
test.describe('Command Shortcuts', () => {
let dashboard: DashboardPage;
let context: any;
test.beforeEach(async ({ page }) => {
context = await setup({ page, isEmptyProject: false, isSuperUser: true });
dashboard = new DashboardPage(page, context.base);
});
test.afterEach(async () => {
await unsetup(context);
});
test('Verify Command J Docs', async ({ page }) => {
await page.waitForTimeout(1000);
await dashboard.cmdJ.openCmdJ();
await expect(dashboard.cmdJ.get()).toBeVisible();
await dashboard.cmdJ.searchText('Column');
await page.keyboard.press('Escape');
await expect(dashboard.cmdJ.get()).toBeHidden();
await dashboard.signOut();
await page.waitForTimeout(2000);
await dashboard.cmdJ.openCmdJ();
await expect(dashboard.cmdJ.get()).toBeHidden();
});
test('Verify Command K', async ({ page }) => {
await page.waitForTimeout(1000);
await dashboard.cmdK.openCmdK();
await expect(dashboard.cmdK.get()).toBeVisible();
await page.keyboard.press('Escape');
await expect(dashboard.cmdK.get()).toBeHidden();
await dashboard.cmdK.openCmdK();
await dashboard.cmdK.searchText('CustomerList');
await expect(dashboard.get().locator('.nc-active-view-title')).toContainText('Default View');
await dashboard.signOut();
await page.waitForTimeout(1000);
await dashboard.cmdK.openCmdK();
await expect(dashboard.cmdK.get()).toBeHidden();
});
test('Verify Command L Recent Switch', async ({ page }) => {
await page.waitForTimeout(1000);
await dashboard.cmdL.openCmdL();
await dashboard.cmdL.isCmdLVisible();
await page.keyboard.press('Escape');
await dashboard.cmdL.isCmdLNotVisible();
await dashboard.treeView.openTable({ title: 'Actor' });
await dashboard.treeView.openTable({ title: 'Address' });
await dashboard.treeView.openTable({ title: 'Category' });
await dashboard.treeView.openTable({ title: 'City' });
await dashboard.treeView.openTable({ title: 'Country' });
await page.waitForTimeout(1000);
await dashboard.cmdL.openCmdL();
await page.waitForTimeout(1000);
await dashboard.cmdL.moveDown();
await dashboard.cmdL.moveDown();
await dashboard.cmdL.moveDown();
await dashboard.cmdL.openRecent();
await page.waitForTimeout(1000);
expect(await dashboard.cmdL.getActiveViewTitle()).toBe('Default View');
expect(await dashboard.cmdL.getActiveTableTitle()).toBe('Address');
await dashboard.signOut();
await dashboard.cmdL.openCmdL();
await dashboard.cmdL.isCmdLNotVisible();
});
});
Loading…
Cancel
Save