const { _electron: electron } = require('@playwright/test') const { test: it } = require('@playwright/test') const { describe } = it it.setTimeout(1000000) 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 { setupSftpConnection, createFolder, createFile, deleteItem, enterFolder, navigateToParentFolder, selectItemsWithCtrlOrCmd, closeApp } = require('./common/common') describe('multi-file selection operations', function () { it('should properly handle single and multi-file selection with modifier keys', async function () { const electronApp = await electron.launch(appOptions) const client = await electronApp.firstWindow() extendClient(client, electronApp) await delay(3500) log('019.file-select.spec.js: app launched') // Set up SFTP connection await setupSftpConnection(client) log('019.file-select.spec.js: sftp connected') // Test both local and remote file systems await testMultiFileSelection(client, 'local') log('019.file-select.spec.js: local selection tested') await testMultiFileSelection(client, 'remote') log('019.file-select.spec.js: remote selection tested') await closeApp(electronApp, __filename) log('019.file-select.spec.js: app closed') }) }) async function testMultiFileSelection (client, type) { // Create a parent test folder const testFolderName = `selection-test-folder-${Date.now()}` await createFolder(client, type, testFolderName) // Enter the test folder await enterFolder(client, type, testFolderName) await delay(2000) // Create multiple files and folders for testing selection const itemNames = [ `file-1-${Date.now()}.txt`, `file-2-${Date.now()}.txt`, `file-3-${Date.now()}.txt`, `folder-1-${Date.now()}`, `folder-2-${Date.now()}` ] // Create the test items for (let i = 0; i < 3; i++) { await createFile(client, type, itemNames[i]) } for (let i = 3; i < 5; i++) { await createFolder(client, type, itemNames[i]) } // Test 1: Single click selection await client.click(`.session-current .file-list.${type} .sftp-item[title="${itemNames[0]}"]`) await delay(500) // Verify only one item is selected const fileItems = await client.locator(`.session-current .file-list.${type} .real-file-item`) let selectedCount = await countSelectedItems(client, fileItems) expect(selectedCount).toBe(1) // Verify the correct item is selected const firstItemSelected = await client.locator(`.session-current .file-list.${type} .sftp-item[title="${itemNames[0]}"]`) const hasSelectedClass = await firstItemSelected.evaluate(el => el.classList.contains('selected')) expect(hasSelectedClass).toBe(true) // Test 2: Click another item should deselect the first await client.click(`.session-current .file-list.${type} .sftp-item[title="${itemNames[1]}"]`) await delay(500) // Verify only the second item is selected now selectedCount = await countSelectedItems(client, fileItems) expect(selectedCount).toBe(1) const secondItemSelected = await client.locator(`.session-current .file-list.${type} .sftp-item[title="${itemNames[1]}"]`) const secondHasSelectedClass = await secondItemSelected.evaluate(el => el.classList.contains('selected')) expect(secondHasSelectedClass).toBe(true) // Verify first item is no longer selected const firstItemStillSelected = await firstItemSelected.evaluate(el => el.classList.contains('selected')) expect(firstItemStillSelected).toBe(false) // Test 3: Ctrl/Cmd+click for multi-selection // Select items at index 0, 2, and 4 (first file, third file, and second folder) await selectItemsWithCtrlOrCmd(client, type, [0, 2, 4]) await delay(1000) // Verify exactly three items are selected selectedCount = await countSelectedItems(client, fileItems) expect(selectedCount).toBe(3) // Verify the specific items are selected const itemsToCheck = [itemNames[0], itemNames[2], itemNames[4]] for (const itemName of itemsToCheck) { const item = await client.locator(`.session-current .file-list.${type} .sftp-item[title="${itemName}"]`) const isSelected = await item.evaluate(el => el.classList.contains('selected')) expect(isSelected).toBe(true) } // Test 4: Single click again should deselect all and select only one await client.click(`.session-current .file-list.${type} .sftp-item[title="${itemNames[3]}"]`) await delay(500) // Verify only one item is selected selectedCount = await countSelectedItems(client, fileItems) expect(selectedCount).toBe(1) // Verify the fourth item (folder-1) is selected const fourthItemSelected = await client.locator(`.session-current .file-list.${type} .sftp-item[title="${itemNames[3]}"]`) const fourthHasSelectedClass = await fourthItemSelected.evaluate(el => el.classList.contains('selected')) expect(fourthHasSelectedClass).toBe(true) // Navigate back to parent folder await navigateToParentFolder(client, type) await delay(1500) // Clean up by deleting the test folder await deleteItem(client, type, testFolderName) await delay(2000) } async function countSelectedItems (client, fileItems) { const count = await fileItems.count() let selectedCount = 0 for (let i = 0; i < count; i++) { const hasSelectedClass = await fileItems.nth(i).evaluate(el => el.classList.contains('selected')) if (hasSelectedClass) { selectedCount++ } } return selectedCount }