electerm--electerm
185 行
7.4 KiB
JavaScript
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')
|
|
})
|
|
})
|