133 lines
4.4 KiB
TypeScript
133 lines
4.4 KiB
TypeScript
import { test, expect, type Page } from '@playwright/test'
|
|
import fs from 'fs'
|
|
import path from 'path'
|
|
import {
|
|
createFixtureVaultCopy,
|
|
openFixtureVaultDesktopHarness,
|
|
removeFixtureVaultCopy,
|
|
} from '../helpers/fixtureVault'
|
|
import { dispatchShortcutEvent } from './testBridge'
|
|
|
|
const USE_META_SHORTCUTS = process.platform === 'darwin'
|
|
const CRLF_INBOX_NOTE_RELATIVE_PATH = path.join('note', 'crlf-inbox-syntax.md')
|
|
|
|
let tempVaultDir: string
|
|
|
|
function crlfInboxNotePath() {
|
|
return path.join(tempVaultDir, CRLF_INBOX_NOTE_RELATIVE_PATH)
|
|
}
|
|
|
|
function seedCrlfInboxNote() {
|
|
fs.writeFileSync(
|
|
crlfInboxNotePath(),
|
|
[
|
|
'---',
|
|
'type: Note',
|
|
'related_to: "[[Alpha Project]]"',
|
|
'---',
|
|
'# CRLF Inbox Syntax',
|
|
'',
|
|
'This note should remain visible after organize.',
|
|
'',
|
|
].join('\r\n'),
|
|
)
|
|
}
|
|
|
|
function frontmatterDelimiterLineCount(content: string): number {
|
|
return content.split(/\r?\n/).filter((line) => line === '---').length
|
|
}
|
|
|
|
async function focusNoteList(page: Page) {
|
|
const container = page.getByTestId('note-list-container')
|
|
await container.focus()
|
|
await expect(container).toBeFocused()
|
|
}
|
|
|
|
async function dispatchCommandShortcut(page: Page, key: string, code: string) {
|
|
await dispatchShortcutEvent(page, {
|
|
key,
|
|
code,
|
|
metaKey: USE_META_SHORTCUTS,
|
|
ctrlKey: !USE_META_SHORTCUTS,
|
|
shiftKey: false,
|
|
altKey: false,
|
|
bubbles: true,
|
|
cancelable: true,
|
|
})
|
|
}
|
|
|
|
async function selectVisibleInboxBatch(page: Page) {
|
|
await focusNoteList(page)
|
|
await dispatchCommandShortcut(page, 'a', 'KeyA')
|
|
await expect(page.getByTestId('bulk-action-bar')).toBeVisible({ timeout: 5_000 })
|
|
}
|
|
|
|
async function selectTopNav(page: Page, label: string) {
|
|
await page.getByTestId('sidebar-top-nav').getByText(label, { exact: true }).click()
|
|
}
|
|
|
|
async function openCrlfInboxNote(page: Page) {
|
|
await selectTopNav(page, 'Inbox')
|
|
const noteRow = page.locator(`[data-note-path="${crlfInboxNotePath()}"]`)
|
|
await expect(noteRow).toBeVisible({ timeout: 5_000 })
|
|
await noteRow.click()
|
|
await expect(page.getByRole('heading', { name: 'CRLF Inbox Syntax', level: 1 })).toBeVisible({ timeout: 5_000 })
|
|
}
|
|
|
|
test.describe('multi-selection shortcuts', () => {
|
|
test.beforeEach(() => {
|
|
tempVaultDir = createFixtureVaultCopy()
|
|
})
|
|
|
|
test.afterEach(() => {
|
|
removeFixtureVaultCopy(tempVaultDir)
|
|
})
|
|
|
|
test('Cmd/Ctrl+E organizes the full Inbox multi-selection @smoke', async ({ page }) => {
|
|
await openFixtureVaultDesktopHarness(page, tempVaultDir)
|
|
await selectVisibleInboxBatch(page)
|
|
|
|
await dispatchCommandShortcut(page, 'e', 'KeyE')
|
|
|
|
await expect(page.getByTestId('bulk-action-bar')).toHaveCount(0)
|
|
await expect(page.getByText('All notes are organized')).toBeVisible({ timeout: 5_000 })
|
|
})
|
|
|
|
test('Cmd/Ctrl+E organizes a CRLF Inbox note without duplicating frontmatter @smoke', async ({ page }) => {
|
|
seedCrlfInboxNote()
|
|
await openFixtureVaultDesktopHarness(page, tempVaultDir)
|
|
await openCrlfInboxNote(page)
|
|
|
|
await page.locator('.bn-editor').click()
|
|
await dispatchCommandShortcut(page, 'e', 'KeyE')
|
|
|
|
await expect.poll(() => fs.readFileSync(crlfInboxNotePath(), 'utf8')).toContain('_organized: true')
|
|
const organizedContent = fs.readFileSync(crlfInboxNotePath(), 'utf8')
|
|
expect(frontmatterDelimiterLineCount(organizedContent)).toBe(2)
|
|
expect(organizedContent).toContain('type: Note')
|
|
expect(organizedContent).toContain('related_to: "[[Alpha Project]]"')
|
|
|
|
await expect(page.locator(`[data-note-path="${crlfInboxNotePath()}"]`)).toHaveCount(0)
|
|
await selectTopNav(page, 'All Notes')
|
|
await expect(page.locator(`[data-note-path="${crlfInboxNotePath()}"]`)).toBeVisible({ timeout: 5_000 })
|
|
})
|
|
|
|
test('Cmd/Ctrl+Backspace batch-deletes the full visible multi-selection after one confirmation @smoke', async ({ page }) => {
|
|
await openFixtureVaultDesktopHarness(page, tempVaultDir)
|
|
await selectVisibleInboxBatch(page)
|
|
|
|
await dispatchCommandShortcut(page, 'Backspace', 'Backspace')
|
|
|
|
const dialog = page.getByTestId('confirm-delete-dialog')
|
|
const confirmButton = page.getByTestId('confirm-delete-btn')
|
|
await expect(dialog).toBeVisible({ timeout: 5_000 })
|
|
await expect(dialog).toContainText(/Delete \d+ notes permanently\?/)
|
|
|
|
await expect(confirmButton).toBeFocused()
|
|
await page.keyboard.press('Enter')
|
|
|
|
await expect(dialog).toHaveCount(0)
|
|
await expect(page.getByTestId('bulk-action-bar')).toHaveCount(0)
|
|
})
|
|
})
|