项目文件夹

文件
2026-07-13 12:46:20 +08:00

185 行
7.4 KiB
JavaScript

/**
* Terminal command-history test
*
* Verifies:
* 1. Running a command in a local terminal adds it to cmd history.
* 2. Clicking the history item re-runs the command.
* 3. Deleting a history item removes it from the list.
* 4. History persists across app restarts.
*/
const { _electron: electron } = require('@playwright/test')
const { test: it } = require('@playwright/test')
const { describe } = it
it.setTimeout(10000000)
const delay = require('./common/wait')
const log = require('./common/log')
const appOptions = require('./common/app-options')
const extendClient = require('./common/client-extend')
const { expect } = require('./common/expect')
const { closeApp } = require('./common/common')
// ─── helpers ──────────────────────────────────────────────────────────────────
/** Open the command-history popover in the footer.
* Closes any currently-open popover first so we get a clean open. */
async function openHistoryPopover (client) {
// Click outside any popover to ensure it is closed before reopening
await client.click('.session-current .term-wrap')
await delay(400)
await client.click('.terminal-footer-history .ant-btn')
await delay(800)
}
/** Close the popover by clicking outside of it. */
async function closeHistoryPopover (client) {
await client.click('.session-current .term-wrap')
await delay(400)
}
/**
* Return the text of all visible command-history items.
* The popover must already be open.
*/
async function getHistoryItems (client) {
const items = await client.locator('.cmd-history-item .cmd-history-item-text')
const count = await items.count()
const texts = []
for (let i = 0; i < count; i++) {
texts.push(await items.nth(i).innerText())
}
return texts
}
/**
* Hover over a history item whose text includes `term` to reveal action buttons,
* then click the delete button. The popover must already be open.
*/
async function deleteHistoryItem (client, term) {
const items = client.locator('.cmd-history-item')
const count = await items.count()
for (let i = 0; i < count; i++) {
const txt = await items.nth(i).locator('.cmd-history-item-text').innerText()
if (txt.includes(term)) {
await items.nth(i).hover()
await delay(400)
await items.nth(i).locator('.cmd-history-item-delete').click()
await delay(600)
return
}
}
throw new Error(`History item matching "${term}" not found in popover`)
}
/** Return the cmd strings currently in window.store.terminalCommandHistory. */
async function getStoredHistory (client) {
return client.evaluate(() =>
window.store.terminalCommandHistory.map(i => i.cmd)
)
}
/** Type a command in the terminal and press Enter. */
async function runInTerminal (client, cmd) {
await client.click('.session-current .term-wrap')
await delay(1000)
await client.keyboard.type(cmd)
await delay(300)
await client.keyboard.press('Enter')
await delay(1500)
}
// ─── test ─────────────────────────────────────────────────────────────────────
describe('cmd-history', function () {
it('should add, re-run, delete commands and persist across restarts', async function () {
// ── first session ──────────────────────────────────────────────────────────
let electronApp = await electron.launch(appOptions)
let client = await electronApp.firstWindow()
extendClient(client, electronApp)
await delay(13000)
log('021: app launched (session 1)')
const ts = Date.now()
// Use simple commands without quotes to avoid shell-escaping issues
const cmd1 = `echo cmd-history-test-${ts}`
const cmd2 = `echo cmd-history-persist-${ts}`
// Clear existing history so our unique commands are easy to find
await client.evaluate(() => window.store.clearAllCmdHistory())
await delay(300)
// ── step 1: run cmd1 in terminal → should appear in history ───────────────
await runInTerminal(client, cmd1)
log(`021: ran "${cmd1}" in terminal`)
// Verify via store (ground truth)
const stored1 = await getStoredHistory(client)
log(`021: stored history: ${JSON.stringify(stored1)}`)
expect(stored1.includes(cmd1)).equal(true)
// Verify via UI popover
await openHistoryPopover(client)
const items1 = await getHistoryItems(client)
log(`021: history popover items: ${JSON.stringify(items1)}`)
expect(items1.some(t => t.trim() === cmd1 || t.includes(`cmd-history-test-${ts}`))).equal(true)
// ── step 2: click the item to re-run the command ──────────────────────────
const allItems = client.locator('.cmd-history-item')
const count = await allItems.count()
let clicked = false
for (let i = 0; i < count; i++) {
const txt = await allItems.nth(i).locator('.cmd-history-item-text').innerText()
if (txt.includes(`cmd-history-test-${ts}`)) {
await allItems.nth(i).locator('.cmd-history-item-text').click()
clicked = true
break
}
}
expect(clicked).equal(true)
await delay(2000)
log('021: clicked history item to re-run')
// count in store should have updated (command was re-run)
const stored2 = await getStoredHistory(client)
expect(stored2.includes(cmd1)).equal(true)
// ── step 3: delete the item ────────────────────────────────────────────────
// Reopen popover (clicking the item might or might not have closed it; use
// the helper which first clicks outside to normalise state)
await openHistoryPopover(client)
await deleteHistoryItem(client, `cmd-history-test-${ts}`)
const storedAfterDel = await getStoredHistory(client)
log(`021: history after delete: ${JSON.stringify(storedAfterDel)}`)
expect(storedAfterDel.includes(cmd1)).equal(false)
await closeHistoryPopover(client)
// ── step 4: run cmd2 that should persist after restart ────────────────────
await runInTerminal(client, cmd2)
await delay(2000) // allow store + db flush
log(`021: ran "${cmd2}" in terminal`)
await closeApp(electronApp, __filename)
log('021: session 1 closed')
// ── second session (restart) ───────────────────────────────────────────────
await delay(2000)
electronApp = await electron.launch(appOptions)
client = await electronApp.firstWindow()
extendClient(client, electronApp)
await delay(13000)
log('021: app launched (session 2 – restart)')
// cmd2 must still be in history
const storedRestart = await getStoredHistory(client)
log(`021: history after restart: ${JSON.stringify(storedRestart)}`)
expect(storedRestart.includes(cmd2)).equal(true)
// cmd1 must NOT be in history (was deleted before restart)
expect(storedRestart.includes(cmd1)).equal(false)
await closeApp(electronApp, __filename)
log('021: all cmd-history tests passed')
})
})