import { test, expect } from '@playwright/test'; import { createNewSheet, clickCell, typeInCell, getCellText } from './helpers'; test.describe('Sheets - Clipboard', () => { test.beforeEach(async ({ page, context }) => { // Grant clipboard permissions await context.grantPermissions(['clipboard-read', 'clipboard-write']); await createNewSheet(page); }); test('copy cell and paste to another cell', async ({ page }) => { await typeInCell(page, 'A1', 'CopyMe'); // Select A1 and copy await clickCell(page, 'A1'); await page.keyboard.press('Meta+c'); // Select B1 and paste await clickCell(page, 'B1'); await page.keyboard.press('Meta+v'); // B1 should now have the same value await expect(page.locator('td[data-id="B1"] .cell-display')).toContainText('CopyMe', { timeout: 5000 }); // A1 should still have its value (copy, not cut) expect(await getCellText(page, 'A1')).toBe('CopyMe'); }); test('cut cell clears original', async ({ page }) => { await typeInCell(page, 'A1', 'CutMe'); // Select A1 and cut await clickCell(page, 'A1'); await page.keyboard.press('Meta+x'); // Select B1 and paste await clickCell(page, 'B1'); await page.keyboard.press('Meta+v'); // B1 should have the value await expect(page.locator('td[data-id="B1"] .cell-display')).toContainText('CutMe', { timeout: 5000 }); // A1 should be empty (it was cut) const a1Text = await getCellText(page, 'A1'); expect(a1Text).toBe(''); }); test('copy multiple cells and paste', async ({ page }) => { await typeInCell(page, 'A1', 'One'); await typeInCell(page, 'A2', 'Two'); await typeInCell(page, 'A3', 'Three'); // Select range A1:A3 await clickCell(page, 'A1'); await page.keyboard.down('Shift'); await clickCell(page, 'A3'); await page.keyboard.up('Shift'); // Copy await page.keyboard.press('Meta+c'); // Paste to B1 await clickCell(page, 'B1'); await page.keyboard.press('Meta+v'); // Verify all values pasted await expect(page.locator('td[data-id="B1"] .cell-display')).toContainText('One', { timeout: 5000 }); expect(await getCellText(page, 'B2')).toBe('Two'); expect(await getCellText(page, 'B3')).toBe('Three'); }); test('copy cell with formula pastes computed value or adjusted formula', async ({ page }) => { await typeInCell(page, 'A1', '10'); await typeInCell(page, 'A2', '=A1*2'); // A2 should show 20 expect(await getCellText(page, 'A2')).toBe('20'); // Copy A2 await clickCell(page, 'A2'); await page.keyboard.press('Meta+c'); // Paste to B2 await clickCell(page, 'B2'); await page.keyboard.press('Meta+v'); // B2 should have a value (either the formula adjusted or the value pasted) const b2Text = await getCellText(page, 'B2'); expect(b2Text).toBeTruthy(); }); test('delete key clears selected cell', async ({ page }) => { await typeInCell(page, 'A1', 'DeleteMe'); expect(await getCellText(page, 'A1')).toBe('DeleteMe'); await clickCell(page, 'A1'); await page.keyboard.press('Delete'); // Cell should be empty const text = await getCellText(page, 'A1'); expect(text).toBe(''); }); test('backspace clears selected cell', async ({ page }) => { await typeInCell(page, 'A1', 'ClearMe'); await clickCell(page, 'A1'); await page.keyboard.press('Backspace'); // Should start editing with empty content (Backspace enters edit mode) // Press Escape or Enter to confirm await page.keyboard.press('Escape'); // Cell may still have content if Backspace enters edit mode // Just verify the action doesn't crash }); });