import { expect, test } from "@odoo/hoot"; import { click, hover, queryAllAttributes, queryOne, waitFor, waitForNone } from "@odoo/hoot-dom"; import { animationFrame } from "@odoo/hoot-mock"; import { setupEditor } from "../_helpers/editor"; import { unformat } from "../_helpers/format"; import { getContent } from "../_helpers/selection"; import { undo } from "../_helpers/user_actions"; function availableCommands(menu) { return queryAllAttributes("span div.user-select-none", "name", { root: menu }); } test("should only display the table ui menu if the table isContentEditable=true", async () => { const { el } = await setupEditor(`
11[]
`); expect(".o-we-table-menu").toHaveCount(0); await hover(el.querySelector("td")); await waitFor(".o-we-table-menu"); // 1 menu for columns, and 1 for rows expect(".o-we-table-menu").toHaveCount(2); }); test("should display the table ui menu only if hover on first row/col", async () => { const { el } = await setupEditor(`
1[]2
34
`); expect(".o-we-table-menu").toHaveCount(0); await hover(el.querySelector("td.a")); await waitFor(".o-we-table-menu"); expect("[data-type='column'].o-we-table-menu").toHaveCount(1); expect("[data-type='row'].o-we-table-menu").toHaveCount(1); await hover(el.querySelector("td.b")); await waitForNone("[data-type='row'].o-we-table-menu"); expect("[data-type='column'].o-we-table-menu").toHaveCount(1); await hover(el.querySelector("td.c")); await waitForNone("[data-type='column'].o-we-table-menu"); expect("[data-type='row'].o-we-table-menu").toHaveCount(1); await hover(el.querySelector("td.d")); await waitForNone(".o-we-table-menu"); }); test("should not display the table ui menu if the table element isContentEditable=false", async () => { const { el } = await setupEditor(`
11[]
`); expect(".o-we-table-menu").toHaveCount(0); await hover(el.querySelector("td")); await animationFrame(); expect(".o-we-table-menu").toHaveCount(0); }); test("should not display the table ui menu if we leave the editor content", async () => { const { el } = await setupEditor(`
11[]
`); expect(".o-we-table-menu").toHaveCount(0); await hover(el.querySelector("td")); await animationFrame(); expect(".o-we-table-menu").toHaveCount(2); await hover(el.parentElement); await animationFrame(); expect(".o-we-table-menu").toHaveCount(0); }); test.tags("desktop"); test("should display the resizeCursor if the table element isContentEditable=true", async () => { const { el } = await setupEditor(`
11[]
`); expect(".o_col_resize").toHaveCount(0); expect(".o_row_resize").toHaveCount(0); const td = el.querySelector("td"); const tdBox = td.getBoundingClientRect(); const x = tdBox.x + 1; const y = tdBox.bottom - tdBox.height / 2; await hover(td, { position: { x, y } }); await waitFor(".o_col_resize"); expect(".o_col_resize").toHaveCount(1); }); test("should not display the resizeCursor if the table element isContentEditable=false", async () => { const { el } = await setupEditor(`
11[]
`); expect(".o_col_resize").toHaveCount(0); expect(".o_row_resize").toHaveCount(0); await hover(el.querySelector("td")); await animationFrame(); expect(".o_col_resize").toHaveCount(0); }); test("list of table commands in first column", async () => { const { el } = await setupEditor(`


1[]23
`); expect(".o-we-table-menu").toHaveCount(0); // check list of commands on first column await hover(el.querySelector("td.a")); await waitFor(".o-we-table-menu"); expect("[data-type='column'].o-we-table-menu").toHaveCount(1); expect("[data-type='row'].o-we-table-menu").toHaveCount(1); await click("[data-type='column'].o-we-table-menu"); await waitFor(".dropdown-menu"); await hover(el); await animationFrame(); expect("[data-type='column'].o-we-table-menu").toHaveCount(1); expect("[data-type='row'].o-we-table-menu").toHaveCount(0); expect(availableCommands(queryOne(".dropdown-menu"))).toEqual([ // no move left "move_right", "insert_left", "insert_right", "delete", ]); }); test("list of table commands in second column", async () => { const { el } = await setupEditor(`
1[]23
`); expect(".o-we-table-menu").toHaveCount(0); // check list of commands on second column await hover(el.querySelector("td.b")); await waitFor(".o-we-table-menu"); expect("[data-type='column'].o-we-table-menu").toHaveCount(1); await click("[data-type='column'].o-we-table-menu"); await waitFor(".dropdown-menu"); expect(availableCommands(queryOne(".dropdown-menu"))).toEqual([ "move_left", "move_right", "insert_left", "insert_right", "delete", ]); }); test("list of table commands in last column", async () => { const { el } = await setupEditor(`
1[]23
`); expect(".o-we-table-menu").toHaveCount(0); // check list of commands on last column await hover(el.querySelector("td.c")); await waitFor(".o-we-table-menu"); expect("[data-type='column'].o-we-table-menu").toHaveCount(1); await click("[data-type='column'].o-we-table-menu"); await waitFor(".dropdown-menu"); expect(availableCommands(queryOne(".dropdown-menu"))).toEqual([ "move_left", // no move right "insert_left", "insert_right", "delete", ]); }); test("list of table commands in first row", async () => { const { el } = await setupEditor(`
1[]
2
3
`); expect(".o-we-table-menu").toHaveCount(0); // check list of commands on first row await hover(el.querySelector("td.a")); await waitFor(".o-we-table-menu"); expect("[data-type='column'].o-we-table-menu").toHaveCount(1); expect("[data-type='row'].o-we-table-menu").toHaveCount(1); await click("[data-type='row'].o-we-table-menu"); await waitFor(".dropdown-menu"); await hover(el); await animationFrame(); expect("[data-type='column'].o-we-table-menu").toHaveCount(0); expect("[data-type='row'].o-we-table-menu").toHaveCount(1); expect(availableCommands(queryOne(".dropdown-menu"))).toEqual([ // no move up "move_down", "insert_above", "insert_below", "delete", ]); }); test("list of table commands in second row", async () => { const { el } = await setupEditor(`
1[]
2
3
`); expect(".o-we-table-menu").toHaveCount(0); // check list of commands on second row await hover(el.querySelector("td.b")); await waitFor(".o-we-table-menu"); expect("[data-type='row'].o-we-table-menu").toHaveCount(1); await click("[data-type='row'].o-we-table-menu"); await waitFor(".dropdown-menu"); expect(availableCommands(queryOne(".dropdown-menu"))).toEqual([ "move_up", "move_down", "insert_above", "insert_below", "delete", ]); }); test("list of table commands in last row", async () => { const { el } = await setupEditor(`
1[]
2
3
`); expect(".o-we-table-menu").toHaveCount(0); // check list of commands on last row await hover(el.querySelector("td.c")); await waitFor(".o-we-table-menu"); expect("[data-type='row'].o-we-table-menu").toHaveCount(1); await click("[data-type='row'].o-we-table-menu"); await waitFor(".dropdown-menu"); expect(availableCommands(queryOne(".dropdown-menu"))).toEqual([ "move_up", // no move down "insert_above", "insert_below", "delete", ]); }); test("open/close table menu", async () => { const { el } = await setupEditor(`
1[]
2
3
`); expect(".o-we-table-menu").toHaveCount(0); // check list of commands on first row await hover(el.querySelector("td.a")); await waitFor(".o-we-table-menu"); expect("[data-type='column'].o-we-table-menu").toHaveCount(1); expect("[data-type='row'].o-we-table-menu").toHaveCount(1); await click("[data-type='row'].o-we-table-menu"); await waitFor(".dropdown-menu"); await click("[data-type='row'].o-we-table-menu"); await animationFrame(); expect("[data-type='column'].o-we-table-menu").toHaveCount(0); expect("[data-type='row'].o-we-table-menu").toHaveCount(1); expect(".dropdown-menu").toHaveCount(0); await hover(el); await animationFrame(); expect("[data-type='column'].o-we-table-menu").toHaveCount(0); expect("[data-type='row'].o-we-table-menu").toHaveCount(0); expect(".dropdown-menu").toHaveCount(0); }); test("basic delete column operation", async () => { const { el, editor } = await setupEditor( unformat(`
1[]2
34
`) ); expect(".o-we-table-menu").toHaveCount(0); // hover on td to show col ui await hover(el.querySelector("td.b")); await waitFor(".o-we-table-menu"); // click on it to open dropdown await click(".o-we-table-menu"); await waitFor("div[name='delete']"); // delete column await click("div[name='delete']"); // not sure about selection... expect(getContent(el)).toBe( unformat(`
[]1
3
`) ); undo(editor); expect(getContent(el)).toBe( unformat(`
1[]2
34
`) ); }); test("basic delete row operation", async () => { const { el, editor } = await setupEditor( unformat(`
1[]2
34
`) ); expect(".o-we-table-menu").toHaveCount(0); // hover on td to show col ui await hover(el.querySelector("td.c")); await waitFor(".o-we-table-menu"); // click on it to open dropdown await click(".o-we-table-menu"); await waitFor("div[name='delete']"); // delete row await click("div[name='delete']"); // not sure about selection... expect(getContent(el)).toBe( unformat(`
[]12
`) ); undo(editor); expect(getContent(el)).toBe( unformat(`
1[]2
34
`) ); }); test("insert column left operation", async () => { const { el, editor } = await setupEditor( unformat(`
1[]2
34
`) ); expect(".o-we-table-menu").toHaveCount(0); // hover on td to show col ui await hover(el.querySelector("td.b")); await waitFor(".o-we-table-menu"); // click on it to open dropdown await click(".o-we-table-menu"); await waitFor("div[name='insert_left']"); // insert column left await click("div[name='insert_left']"); expect(getContent(el)).toBe( unformat(`
1[]


2
3


4
`) ); undo(editor); expect(getContent(el)).toBe( unformat(`
1[]2
34
`) ); }); test("insert column right operation", async () => { const { el, editor } = await setupEditor( unformat(`
1[]2
34
`) ); expect(".o-we-table-menu").toHaveCount(0); // hover on td to show col ui await hover(el.querySelector("td.a")); await waitFor("[data-type='column'].o-we-table-menu"); // click on it to open dropdown await click("[data-type='column'].o-we-table-menu"); await waitFor("div[name='insert_right']"); // insert column right await click("div[name='insert_right']"); expect(getContent(el)).toBe( unformat(`
1[]


2
3


4
`) ); undo(editor); expect(getContent(el)).toBe( unformat(`
1[]2
34
`) ); }); test("insert row above operation", async () => { const { el, editor } = await setupEditor( unformat(`
1[]2
34
`) ); expect(".o-we-table-menu").toHaveCount(0); // hover on td to show row ui await hover(el.querySelector("td.c")); await waitFor(".o-we-table-menu"); // click on it to open dropdown await click(".o-we-table-menu"); await waitFor("div[name='insert_above']"); // insert row above await click("div[name='insert_above']"); expect(getContent(el)).toBe( unformat(`
1[] 2



3 4
`) ); undo(editor); expect(getContent(el)).toBe( unformat(`
1[]2
34
`) ); }); test("insert row below operation", async () => { const { el, editor } = await setupEditor( unformat(`
1[]2
34
`) ); expect(".o-we-table-menu").toHaveCount(0); // hover on td to show row ui await hover(el.querySelector("td.a")); await waitFor("[data-type='row'].o-we-table-menu"); // click on it to open dropdown await click("[data-type='row'].o-we-table-menu"); await waitFor("div[name='insert_below']"); // insert row below await click("div[name='insert_below']"); expect(getContent(el)).toBe( unformat(`
1[] 2



3 4
`) ); undo(editor); expect(getContent(el)).toBe( unformat(`
1[]2
34
`) ); }); test("move column left operation", async () => { const { el, editor } = await setupEditor( unformat(`
12[]
34
`) ); expect(".o-we-table-menu").toHaveCount(0); // hover on td to show row ui await hover(el.querySelector("td.b")); await waitFor("[data-type='column'].o-we-table-menu"); // click on it to open dropdown await click("[data-type='column'].o-we-table-menu"); await waitFor("div[name='move_left']"); // move column left await click("div[name='move_left']"); expect(getContent(el)).toBe( unformat(`
2[]1
43
`) ); undo(editor); expect(getContent(el)).toBe( unformat(`
12[]
34
`) ); }); test("move column right operation", async () => { const { el, editor } = await setupEditor( unformat(`
12[]
34
`) ); expect(".o-we-table-menu").toHaveCount(0); // hover on td to show row ui await hover(el.querySelector("td.a")); await waitFor("[data-type='column'].o-we-table-menu"); // click on it to open dropdown await click("[data-type='column'].o-we-table-menu"); await waitFor("div[name='move_right']"); // move column right await click("div[name='move_right']"); expect(getContent(el)).toBe( unformat(`
2[]1
43
`) ); undo(editor); expect(getContent(el)).toBe( unformat(`
12[]
34
`) ); }); test("move row above operation", async () => { const { el, editor } = await setupEditor( unformat(`
1[]2
34
`) ); expect(".o-we-table-menu").toHaveCount(0); // hover on td to show row ui await hover(el.querySelector("td.c")); await waitFor("[data-type='row'].o-we-table-menu"); // click on it to open dropdown await click("[data-type='row'].o-we-table-menu"); await waitFor("div[name='move_up']"); // move row up await click("div[name='move_up']"); expect(getContent(el)).toBe( unformat(`
34
1[]2
`) ); undo(editor); expect(getContent(el)).toBe( unformat(`
1[]2
34
`) ); }); test("preserve table rows width on move row above operation", async () => { const { el } = await setupEditor( unformat(`
1[]2
34
56
`) ); expect(".o-we-table-menu").toHaveCount(0); // hover on td to show row ui await hover(el.querySelector("td.c")); await waitFor("[data-type='row'].o-we-table-menu"); // click on it to open dropdown await click("[data-type='row'].o-we-table-menu"); await waitFor("div[name='move_up']"); // move row up await click("div[name='move_up']"); expect(getContent(el)).toBe( unformat(`
34
1[]2
56
`) ); }); test("move row below operation", async () => { const { el, editor } = await setupEditor( unformat(`
1[]2
34
`) ); expect(".o-we-table-menu").toHaveCount(0); // hover on td to show row ui await hover(el.querySelector("td.a")); await waitFor("[data-type='row'].o-we-table-menu"); // click on it to open dropdown await click("[data-type='row'].o-we-table-menu"); await waitFor("div[name='move_down']"); // move row below await click("div[name='move_down']"); expect(getContent(el)).toBe( unformat(`
34
1[]2
`) ); undo(editor); expect(getContent(el)).toBe( unformat(`
1[]2
34
`) ); }); test("preserve table rows width on move row below operation", async () => { const { el } = await setupEditor( unformat(`
1[]2
34
56
`) ); expect(".o-we-table-menu").toHaveCount(0); // hover on td to show row ui await hover(el.querySelector("td.a")); await waitFor("[data-type='row'].o-we-table-menu"); // click on it to open dropdown await click("[data-type='row'].o-we-table-menu"); await waitFor("div[name='move_down']"); // move row below await click("div[name='move_down']"); expect(getContent(el)).toBe( unformat(`
34
1[]2
56
`) ); }); test("reset table size to remove custom width", async () => { const { el, editor } = await setupEditor( unformat(`
1[]
2
`) ); expect(".o-we-table-menu").toHaveCount(0); await hover(el.querySelector("td.a")); await waitFor(".o-we-table-menu"); expect("[data-type='row'].o-we-table-menu").toHaveCount(1); await click("[data-type='row'].o-we-table-menu"); await waitFor(".dropdown-menu"); await click(queryOne(".dropdown-menu [name='reset_size']")); expect(getContent(el)).toBe( unformat(`
1[]
2
`) ); undo(editor); expect(getContent(el)).toBe( unformat(`
1[]
2
`) ); }); test("reset table size to remove custom height", async () => { const { el, editor } = await setupEditor( unformat(`
1[]
2
`) ); expect(".o-we-table-menu").toHaveCount(0); await hover(el.querySelector("td.a")); await waitFor(".o-we-table-menu"); expect("[data-type='row'].o-we-table-menu").toHaveCount(1); await click("[data-type='row'].o-we-table-menu"); await waitFor(".dropdown-menu"); await click(queryOne(".dropdown-menu [name='reset_size']")); expect(getContent(el)).toBe( unformat(`
1[]
2
`) ); undo(editor); expect(getContent(el)).toBe( unformat(`
1[]
2
`) ); });