Full document, spreadsheet, slideshow, and diagram tooling
1import { test, expect } from '@playwright/test';
2import { createNewSheet, clickCell, typeInCell, getCellText } from './helpers';
3
4test.describe('Sheets - Cell Formatting', () => {
5 test.beforeEach(async ({ page }) => {
6 await createNewSheet(page);
7 });
8
9 test('apply bold via toolbar button', async ({ page }) => {
10 await typeInCell(page, 'A1', 'Bold Text');
11 await clickCell(page, 'A1');
12
13 await page.click('#tb-bold');
14
15 // Cell display should have bold style
16 const cellDisplay = page.locator('td[data-id="A1"] .cell-display');
17 await expect(cellDisplay).toHaveCSS('font-weight', '600');
18 });
19
20 test('apply italic via toolbar button', async ({ page }) => {
21 await typeInCell(page, 'A1', 'Italic Text');
22 await clickCell(page, 'A1');
23
24 await page.click('#tb-italic');
25
26 const cellDisplay = page.locator('td[data-id="A1"] .cell-display');
27 await expect(cellDisplay).toHaveCSS('font-style', 'italic');
28 });
29
30 test('apply bold via keyboard shortcut', async ({ page }) => {
31 await typeInCell(page, 'A1', 'KB Bold');
32 await clickCell(page, 'A1');
33
34 await page.keyboard.press('Meta+b');
35
36 const cellDisplay = page.locator('td[data-id="A1"] .cell-display');
37 await expect(cellDisplay).toHaveCSS('font-weight', '600');
38 });
39
40 test('change text color via color picker', async ({ page }) => {
41 await typeInCell(page, 'A1', 'Colored');
42 await clickCell(page, 'A1');
43
44 // Set text color via the color input
45 await page.locator('#tb-text-color').evaluate((el: HTMLInputElement) => {
46 // Programmatically set color and dispatch event
47 el.value = '#ff0000';
48 el.dispatchEvent(new Event('input', { bubbles: true }));
49 });
50
51 // Verify the cell display has the color applied
52 const cellDisplay = page.locator('td[data-id="A1"] .cell-display');
53 const color = await cellDisplay.evaluate(el => getComputedStyle(el).color);
54 // Should be red (rgb(255, 0, 0))
55 expect(color).toMatch(/rgb\(255,\s*0,\s*0\)/);
56 });
57
58 test('change background color via color picker', async ({ page }) => {
59 await typeInCell(page, 'A1', 'Highlighted');
60 await clickCell(page, 'A1');
61
62 await page.locator('#tb-bg-color').evaluate((el: HTMLInputElement) => {
63 el.value = '#ffff00';
64 el.dispatchEvent(new Event('input', { bubbles: true }));
65 });
66
67 const cellDisplay = page.locator('td[data-id="A1"] .cell-display');
68 const bg = await cellDisplay.evaluate(el => getComputedStyle(el).backgroundColor);
69 // Should be yellow
70 expect(bg).toMatch(/rgb\(255,\s*255,\s*0\)/);
71 });
72
73 test('apply currency format shows dollar sign', async ({ page }) => {
74 await typeInCell(page, 'A1', '1234.56');
75 await clickCell(page, 'A1');
76
77 // Select currency format from the dropdown
78 await page.selectOption('#tb-format', 'currency');
79
80 const text = await getCellText(page, 'A1');
81 expect(text).toContain('$');
82 });
83
84 test('apply percent format shows percent sign', async ({ page }) => {
85 await typeInCell(page, 'A1', '0.75');
86 await clickCell(page, 'A1');
87
88 await page.selectOption('#tb-format', 'percent');
89
90 const text = await getCellText(page, 'A1');
91 expect(text).toContain('%');
92 });
93
94 test('change font size', async ({ page }) => {
95 await typeInCell(page, 'A1', 'Big Text');
96 await clickCell(page, 'A1');
97
98 await page.selectOption('#tb-font-size', '20');
99
100 const cellDisplay = page.locator('td[data-id="A1"] .cell-display');
101 const fontSize = await cellDisplay.evaluate(el => getComputedStyle(el).fontSize);
102 // 20pt should be larger than default
103 expect(parseFloat(fontSize)).toBeGreaterThan(14);
104 });
105
106 test('change font family', async ({ page }) => {
107 await typeInCell(page, 'A1', 'Serif Text');
108 await clickCell(page, 'A1');
109
110 await page.selectOption('#tb-font-family', 'serif');
111
112 const cellDisplay = page.locator('td[data-id="A1"] .cell-display');
113 const fontFamily = await cellDisplay.evaluate(el => getComputedStyle(el).fontFamily);
114 expect(fontFamily).toMatch(/serif/i);
115 });
116
117 test('underline via toolbar button', async ({ page }) => {
118 await typeInCell(page, 'A1', 'Underlined');
119 await clickCell(page, 'A1');
120
121 await page.click('#tb-underline');
122
123 const cellDisplay = page.locator('td[data-id="A1"] .cell-display');
124 const decoration = await cellDisplay.evaluate(el => getComputedStyle(el).textDecorationLine);
125 expect(decoration).toContain('underline');
126 });
127
128 test('strikethrough via toolbar button', async ({ page }) => {
129 await typeInCell(page, 'A1', 'Struck');
130 await clickCell(page, 'A1');
131
132 await page.click('#tb-strikethrough');
133
134 const cellDisplay = page.locator('td[data-id="A1"] .cell-display');
135 const decoration = await cellDisplay.evaluate(el => getComputedStyle(el).textDecorationLine);
136 expect(decoration).toContain('line-through');
137 });
138
139 test('number format shows plain number', async ({ page }) => {
140 await typeInCell(page, 'A1', '1234');
141 await clickCell(page, 'A1');
142
143 await page.selectOption('#tb-format', 'number');
144
145 const text = await getCellText(page, 'A1');
146 // Should be formatted as a number (may include commas)
147 expect(text).toMatch(/1,?234/);
148 });
149});