From 842bf9c0e11eebab44707ae1aa6869465e07123c Mon Sep 17 00:00:00 2001 From: umaranis Date: Fri, 10 Nov 2023 01:08:28 +1100 Subject: [PATCH] test: unmerge cells --- .../src/__tests__/e2e/Tables.spec.mjs | 241 ++++++++++++++---- .../playground/src/__tests__/utils/index.mjs | 42 +-- 2 files changed, 208 insertions(+), 75 deletions(-) diff --git a/demos/playground/src/__tests__/e2e/Tables.spec.mjs b/demos/playground/src/__tests__/e2e/Tables.spec.mjs index ebfa524..61a6820 100644 --- a/demos/playground/src/__tests__/e2e/Tables.spec.mjs +++ b/demos/playground/src/__tests__/e2e/Tables.spec.mjs @@ -37,6 +37,7 @@ import { selectCellsFromTableCords, selectFromAdditionalStylesDropdown, test, + unmergeTableCell, } from '../utils/index.mjs'; async function fillTablePartiallyWithText(page) { @@ -62,7 +63,7 @@ async function fillTablePartiallyWithText(page) { test.describe('Tables', () => { test.fixme(); - test.beforeEach(({isCollab, page}) => initialize({isCollab, page})); + test.beforeEach(({ isCollab, page }) => initialize({ isCollab, page })); test(`Can a table be inserted from the toolbar`, async ({ page, isPlainText, @@ -97,11 +98,11 @@ test.describe('Tables', () => {


`, undefined, - {ignoreClasses: true}, + { ignoreClasses: true }, ); }); - test(`Can type inside of table cell`, async ({page, isPlainText}) => { + test(`Can type inside of table cell`, async ({ page, isPlainText }) => { test.skip(isPlainText); await focusEditor(page); @@ -134,11 +135,11 @@ test.describe('Tables', () => {


`, undefined, - {ignoreClasses: true}, + { ignoreClasses: true }, ); }); - test(`Can navigate table with keyboard`, async ({page, isPlainText}) => { + test(`Can navigate table with keyboard`, async ({ page, isPlainText }) => { test.skip(isPlainText); await focusEditor(page); @@ -177,7 +178,7 @@ test.describe('Tables', () => {


`, undefined, - {ignoreClasses: true}, + { ignoreClasses: true }, ); }); @@ -193,8 +194,8 @@ test.describe('Tables', () => { await fillTablePartiallyWithText(page); await selectCellsFromTableCords( page, - {x: 0, y: 0}, - {x: 1, y: 1}, + { x: 0, y: 0 }, + { x: 1, y: 1 }, true, false, ); @@ -261,7 +262,7 @@ test.describe('Tables', () => {


`, - {ignoreClasses: true}, + { ignoreClasses: true }, ); }); @@ -379,11 +380,11 @@ test.describe('Tables', () => {


`, - {ignoreClasses: true}, + { ignoreClasses: true }, ); }); - test(`Can style text using Table selection`, async ({page, isPlainText}) => { + test(`Can style text using Table selection`, async ({ page, isPlainText }) => { test.skip(isPlainText); await focusEditor(page); @@ -392,8 +393,8 @@ test.describe('Tables', () => { await fillTablePartiallyWithText(page); await selectCellsFromTableCords( page, - {x: 0, y: 0}, - {x: 1, y: 1}, + { x: 0, y: 0 }, + { x: 1, y: 1 }, true, false, ); @@ -465,7 +466,7 @@ test.describe('Tables', () => {


`, - {ignoreClasses: true}, + { ignoreClasses: true }, ); }); @@ -481,8 +482,8 @@ test.describe('Tables', () => { await fillTablePartiallyWithText(page); await selectCellsFromTableCords( page, - {x: 0, y: 0}, - {x: 1, y: 1}, + { x: 0, y: 0 }, + { x: 1, y: 1 }, true, false, ); @@ -545,11 +546,11 @@ test.describe('Tables', () => {


`, undefined, - {ignoreClasses: true}, + { ignoreClasses: true }, ); }); - test(`Can clear text using Table selection`, async ({page, isPlainText}) => { + test(`Can clear text using Table selection`, async ({ page, isPlainText }) => { test.skip(isPlainText); await focusEditor(page); @@ -558,8 +559,8 @@ test.describe('Tables', () => { await fillTablePartiallyWithText(page); await selectCellsFromTableCords( page, - {x: 0, y: 0}, - {x: 1, y: 1}, + { x: 0, y: 0 }, + { x: 1, y: 1 }, true, false, ); @@ -598,7 +599,7 @@ test.describe('Tables', () => {


`, undefined, - {ignoreClasses: true}, + { ignoreClasses: true }, ); }); @@ -649,7 +650,7 @@ test.describe('Tables', () => {


`, - {ignoreClasses: true}, + { ignoreClasses: true }, ); }); @@ -731,11 +732,11 @@ test.describe('Tables', () => {


`, - {ignoreClasses: true}, + { ignoreClasses: true }, ); }); - test(`Horizontal rule inside cell`, async ({page, isPlainText}) => { + test(`Horizontal rule inside cell`, async ({ page, isPlainText }) => { test.skip(isPlainText); await focusEditor(page); @@ -762,7 +763,7 @@ test.describe('Tables', () => {


`, undefined, - {ignoreClasses: true}, + { ignoreClasses: true }, ); }); @@ -916,11 +917,11 @@ test.describe('Tables', () => { ); }); - test('Merge cells', async ({page, isPlainText}) => { + test('Merge/unmerge cells (1)', async ({ page, isPlainText }) => { test.skip(isPlainText); if (IS_COLLAB) { // The contextual menu positioning needs fixing (it's hardcoded to show on the right side) - page.setViewportSize({height: 1000, width: 3000}); + page.setViewportSize({ height: 1000, width: 3000 }); } await focusEditor(page); @@ -934,13 +935,12 @@ test.describe('Tables', () => { await page.keyboard.type('second'); await selectCellsFromTableCords( page, - {x: 1, y: 0}, - {x: 2, y: 0}, + { x: 1, y: 0 }, + { x: 2, y: 0 }, true, true, ); await mergeTableCells(page); - await assertHTML( page, html` @@ -964,6 +964,11 @@ test.describe('Tables', () => {


`, + ); + + await unmergeTableCell(page); + await assertHTML( + page, html`


@@ -973,14 +978,140 @@ test.describe('Tables', () => {


+ + +
+ class="PlaygroundEditorTheme__tableCell PlaygroundEditorTheme__tableCellHeader"> +

+ first +

+

+


+ `, + ); + }); + + test('Merge/unmerge cells (2)', async ({ page, isPlainText }) => { + test.skip(isPlainText); + if (IS_COLLAB) { + // The contextual menu positioning needs fixing (it's hardcoded to show on the right side) + page.setViewportSize({ height: 1000, width: 3000 }); + } + + await focusEditor(page); + + await insertTable(page, 3, 3); + + await click(page, '.PlaygroundEditorTheme__tableCell'); + await moveRight(page, 1); + await page.keyboard.type('first'); + await page.keyboard.press('Tab'); + await page.keyboard.type('second'); + await selectCellsFromTableCords( + page, + { x: 1, y: 1 }, + { x: 2, y: 2 }, + false, + false, + ); + await mergeTableCells(page); + await assertHTML( + page, + html` +


+ + + + + + + + + + + + + +
+


+
+

+ first +

+
+

+ second +

+
+


+
+


+
+


+
+


+ `, + ); + + await unmergeTableCell(page); + await assertHTML( + page, + html` +


+ + + + + + + + + + + + + + +
+


+

first

+

+ second +

+
+


+
+


+

+


+



@@ -1002,8 +1133,8 @@ test.describe('Tables', () => { await moveDown(page, 1); await selectCellsFromTableCords( page, - {x: 0, y: 0}, - {x: 0, y: 1}, + { x: 0, y: 0 }, + { x: 0, y: 1 }, true, true, ); @@ -1012,8 +1143,8 @@ test.describe('Tables', () => { await moveRight(page, 1); await selectCellsFromTableCords( page, - {x: 1, y: 0}, - {x: 2, y: 0}, + { x: 1, y: 0 }, + { x: 2, y: 0 }, true, true, ); @@ -1021,8 +1152,8 @@ test.describe('Tables', () => { await selectCellsFromTableCords( page, - {x: 0, y: 0}, - {x: 1, y: 0}, + { x: 0, y: 0 }, + { x: 1, y: 0 }, true, true, ); @@ -1121,7 +1252,7 @@ test.describe('Tables', () => { test.skip(isPlainText); if (IS_COLLAB) { // The contextual menu positioning needs fixing (it's hardcoded to show on the right side) - page.setViewportSize({height: 1000, width: 3000}); + page.setViewportSize({ height: 1000, width: 3000 }); } await focusEditor(page); @@ -1131,8 +1262,8 @@ test.describe('Tables', () => { await click(page, '.PlaygroundEditorTheme__tableCell'); await selectCellsFromTableCords( page, - {x: 1, y: 0}, - {x: 1, y: 1}, + { x: 1, y: 0 }, + { x: 1, y: 1 }, true, false, ); @@ -1179,7 +1310,7 @@ test.describe('Tables', () => { test.skip(isPlainText); if (IS_COLLAB) { // The contextual menu positioning needs fixing (it's hardcoded to show on the right side) - page.setViewportSize({height: 1000, width: 3000}); + page.setViewportSize({ height: 1000, width: 3000 }); } await focusEditor(page); @@ -1189,8 +1320,8 @@ test.describe('Tables', () => { await click(page, '.PlaygroundEditorTheme__tableCell'); await selectCellsFromTableCords( page, - {x: 0, y: 0}, - {x: 1, y: 0}, + { x: 0, y: 0 }, + { x: 1, y: 0 }, true, true, ); @@ -1235,7 +1366,7 @@ test.describe('Tables', () => { test.skip(isPlainText); if (IS_COLLAB) { // The contextual menu positioning needs fixing (it's hardcoded to show on the right side) - page.setViewportSize({height: 1000, width: 3000}); + page.setViewportSize({ height: 1000, width: 3000 }); } await focusEditor(page); @@ -1244,8 +1375,8 @@ test.describe('Tables', () => { await selectCellsFromTableCords( page, - {x: 1, y: 1}, - {x: 1, y: 3}, + { x: 1, y: 1 }, + { x: 1, y: 3 }, false, false, ); @@ -1253,8 +1384,8 @@ test.describe('Tables', () => { await selectCellsFromTableCords( page, - {x: 0, y: 0}, - {x: 0, y: 1}, + { x: 0, y: 0 }, + { x: 0, y: 1 }, true, true, ); @@ -1294,7 +1425,7 @@ test.describe('Tables', () => { test.skip(isPlainText); if (IS_COLLAB) { // The contextual menu positioning needs fixing (it's hardcoded to show on the right side) - page.setViewportSize({height: 1000, width: 3000}); + page.setViewportSize({ height: 1000, width: 3000 }); } await focusEditor(page); @@ -1303,8 +1434,8 @@ test.describe('Tables', () => { await selectCellsFromTableCords( page, - {x: 1, y: 1}, - {x: 3, y: 1}, + { x: 1, y: 1 }, + { x: 3, y: 1 }, false, false, ); @@ -1312,8 +1443,8 @@ test.describe('Tables', () => { await selectCellsFromTableCords( page, - {x: 0, y: 0}, - {x: 1, y: 0}, + { x: 0, y: 0 }, + { x: 1, y: 0 }, true, true, ); @@ -1353,7 +1484,7 @@ test.describe('Tables', () => { test.skip(isPlainText); if (IS_COLLAB) { // The contextual menu positioning needs fixing (it's hardcoded to show on the right side) - page.setViewportSize({height: 1000, width: 3000}); + page.setViewportSize({ height: 1000, width: 3000 }); } await focusEditor(page); diff --git a/demos/playground/src/__tests__/utils/index.mjs b/demos/playground/src/__tests__/utils/index.mjs index 9ea29f9..cc08295 100644 --- a/demos/playground/src/__tests__/utils/index.mjs +++ b/demos/playground/src/__tests__/utils/index.mjs @@ -6,12 +6,12 @@ * */ -import {expect, test as base} from '@playwright/test'; +import { expect, test as base } from '@playwright/test'; import prettier from 'prettier'; -import {URLSearchParams} from 'url'; -import {v4 as uuidv4} from 'uuid'; +import { URLSearchParams } from 'url'; +import { v4 as uuidv4 } from 'uuid'; -import {selectAll} from '../keyboardShortcuts/index.mjs'; +import { selectAll } from '../keyboardShortcuts/index.mjs'; export const E2E_PORT = process.env.E2E_PORT || 5173; export const E2E_BROWSER = process.env.E2E_BROWSER; @@ -60,13 +60,12 @@ export async function initialize({ appSettings.isMaxLength = !!isMaxLength; const urlParams = appSettingsToURLParams(appSettings); - const url = `http://localhost:${E2E_PORT}/${ - isCollab ? 'split/' : '' - }?${urlParams.toString()}`; + const url = `http://localhost:${E2E_PORT}/${isCollab ? 'split/' : '' + }?${urlParams.toString()}`; // Having more horizontal space prevents redundant text wraps for tests // which affects CMD+ArrowRight/Left navigation - page.setViewportSize({height: 1000, width: isCollab ? 2000 : 1000}); + page.setViewportSize({ height: 1000, width: isCollab ? 2000 : 1000 }); await page.goto(url); await exposeLexicalEditor(page); @@ -95,7 +94,7 @@ export const test = base.extend({ legacyEvents: LEGACY_EVENTS, }); -export {expect} from '@playwright/test'; +export { expect } from '@playwright/test'; function appSettingsToURLParams(appSettings) { const params = new URLSearchParams(); @@ -142,7 +141,7 @@ export async function assertHTML( page, expectedHtml, expectedHtmlFrameRight = expectedHtml, - {ignoreClasses = false, ignoreInlineStyles = false} = {}, + { ignoreClasses = false, ignoreInlineStyles = false } = {}, ) { if (IS_COLLAB) { const withRetry = async (fn) => await retryAsync(page, fn, 5); @@ -216,7 +215,7 @@ async function assertSelectionOnPageOrFrame(page, expected) { return path.reverse(); }; - const {anchorNode, anchorOffset, focusNode, focusOffset} = + const { anchorNode, anchorOffset, focusNode, focusOffset } = window.getSelection(); return { @@ -344,7 +343,7 @@ async function pasteFromClipboardPageOrFrame(pageOrFrame, clipboardData) { const [base64, type] = clipboardValue; const res = await fetch(base64); const blob = await res.blob(); - files.push(new File([blob], 'file', {type})); + files.push(new File([blob], 'file', { type })); } } let eventClipboardData; @@ -391,7 +390,7 @@ async function pasteFromClipboardPageOrFrame(pageOrFrame, clipboardData) { } } }, - {canUseBeforeInput, clipboardData}, + { canUseBeforeInput, clipboardData }, ); } @@ -583,7 +582,7 @@ export async function insertImageCaption(page, caption) { } export async function mouseMoveToSelector(page, selector) { - const {x, width, y, height} = await selectorBoundingBox(page, selector); + const { x, width, y, height } = await selectorBoundingBox(page, selector); await page.mouse.move(x + width / 2, y + height / 2); } @@ -639,7 +638,7 @@ export async function dragImage( ); } -export function prettifyHTML(string, {ignoreClasses, ignoreInlineStyles} = {}) { +export function prettifyHTML(string, { ignoreClasses, ignoreInlineStyles } = {}) { let output = string; if (ignoreClasses) { @@ -753,13 +752,11 @@ export async function selectCellsFromTableCords( } const firstRowFirstColumnCell = await leftFrame.locator( - `table:first-of-type > tr:nth-child(${firstCords.y + 1}) > ${ - isFirstHeader ? 'th' : 'td' + `table:first-of-type > tr:nth-child(${firstCords.y + 1}) > ${isFirstHeader ? 'th' : 'td' }:nth-child(${firstCords.x + 1})`, ); const secondRowSecondCell = await leftFrame.locator( - `table:first-of-type > tr:nth-child(${secondCords.y + 1}) > ${ - isSecondHeader ? 'th' : 'td' + `table:first-of-type > tr:nth-child(${secondCords.y + 1}) > ${isSecondHeader ? 'th' : 'td' }:nth-child(${secondCords.x + 1})`, ); @@ -767,7 +764,7 @@ export async function selectCellsFromTableCords( await firstRowFirstColumnCell.click( // This is a test runner quirk. Chrome seems to need two clicks to focus on the // content editable cell before dragging, but Firefox treats it as a double click event. - E2E_BROWSER === 'chromium' ? {clickCount: 2} : {}, + E2E_BROWSER === 'chromium' ? { clickCount: 2 } : {}, ); await dragMouse( @@ -802,6 +799,11 @@ export async function mergeTableCells(page) { await click(page, '.item[data-test-id="table-merge-cells"]'); } +export async function unmergeTableCell(page) { + await click(page, '.table-cell-action-button-container'); + await click(page, '.item[data-test-id="table-unmerge-cells"]'); +} + export async function deleteTableRows(page) { await click(page, '.table-cell-action-button-container'); await click(page, '.item[data-test-id="table-delete-rows"]');