diff --git a/src/tests/frontend-new/helper/padHelper.ts b/src/tests/frontend-new/helper/padHelper.ts index f38a3d825..f4511b4c7 100644 --- a/src/tests/frontend-new/helper/padHelper.ts +++ b/src/tests/frontend-new/helper/padHelper.ts @@ -125,3 +125,23 @@ export const clearPadContent = async (page: Page) => { await page.keyboard.up('Control'); await page.keyboard.press('Delete'); } + +export const writeToPad = async (page: Page, text: string) => { + const body = await getPadBody(page); + await body.click(); + await page.keyboard.type(text); +} + +export const clearAuthorship = async (page: Page) => { + await page.locator("button[data-l10n-id='pad.toolbar.clearAuthorship.title']").click() +} + +export const undoChanges = async (page: Page) => { + await page.keyboard.down('Control'); + await page.keyboard.press('z'); + await page.keyboard.up('Control'); +} + +export const pressUndoButton = async (page: Page) => { + await page.locator('.buttonicon-undo').click() +} diff --git a/src/tests/frontend-new/specs/clear_authorship_color.spec.ts b/src/tests/frontend-new/specs/clear_authorship_color.spec.ts new file mode 100644 index 000000000..6a999a57e --- /dev/null +++ b/src/tests/frontend-new/specs/clear_authorship_color.spec.ts @@ -0,0 +1,87 @@ +import {expect, test} from "@playwright/test"; +import { + clearAuthorship, + clearPadContent, + getPadBody, + goToNewPad, pressUndoButton, + selectAllText, + undoChanges, + writeToPad +} from "../helper/padHelper"; + +test.beforeEach(async ({ page })=>{ + // create a new pad before each test run + await goToNewPad(page); +}) + +test('clear authorship color', async ({page}) => { + // get the inner iframe + const innerFrame = await getPadBody(page); + const padText = "Hello" + + // type some text + await clearPadContent(page); + await writeToPad(page, padText); + const retrievedClasses = await innerFrame.locator('div span').nth(0).getAttribute('class') + expect(retrievedClasses).toContain('author'); + + // select the text + await innerFrame.click() + await selectAllText(page); + + await clearAuthorship(page); + // does the first div include an author class? + const firstDivClass = await innerFrame.locator('div').nth(0).getAttribute('class'); + expect(firstDivClass).not.toContain('author'); + const classes = page.locator('div.disconnected') + expect(await classes.isVisible()).toBe(false) +}) + + +test("makes text clear authorship colors and checks it can't be undone", async function ({page}) { + const innnerPad = await getPadBody(page); + const padText = "Hello" + + // type some text + await clearPadContent(page); + await writeToPad(page, padText); + + // get the first text element out of the inner iframe + const firstDivClass = innnerPad.locator('div').nth(0) + const retrievedClasses = await innnerPad.locator('div span').nth(0).getAttribute('class') + expect(retrievedClasses).toContain('author'); + + + await firstDivClass.focus() + await clearAuthorship(page); + expect(await firstDivClass.getAttribute('class')).not.toContain('author'); + + await undoChanges(page); + const changedFirstDiv = innnerPad.locator('div').nth(0) + expect(await changedFirstDiv.getAttribute('class')).not.toContain('author'); + + + await pressUndoButton(page); + const secondChangedFirstDiv = innnerPad.locator('div').nth(0) + expect(await secondChangedFirstDiv.getAttribute('class')).not.toContain('author'); +}); + + +// Test for https://github.com/ether/etherpad-lite/issues/5128 +test('clears authorship when first line has line attributes', async function ({page}) { + // Make sure there is text with author info. The first line must have a line attribute. + const padBody = await getPadBody(page); + await padBody.click() + await clearPadContent(page); + await writeToPad(page,'Hello') + await page.locator('.buttonicon-insertunorderedlist').click(); + const retrievedClasses = await padBody.locator('div span').nth(0).getAttribute('class') + expect(retrievedClasses).toContain('author'); + await padBody.click() + await selectAllText(page); + await clearAuthorship(page); + const retrievedClasses2 = await padBody.locator('div span').nth(0).getAttribute('class') + expect(retrievedClasses2).not.toContain('author'); + + expect(await page.locator('[class*="author-"]').count()).toBe(0) +}); diff --git a/src/tests/frontend/specs/clear_authorship_colors.js b/src/tests/frontend/specs/clear_authorship_colors.js deleted file mode 100644 index 0dc9c7f2a..000000000 --- a/src/tests/frontend/specs/clear_authorship_colors.js +++ /dev/null @@ -1,125 +0,0 @@ -'use strict'; - -describe('clear authorship colors button', function () { - let padId; - - // create a new pad before each test run - beforeEach(async function () { - padId = await helper.aNewPad(); - }); - - it('makes text clear authorship colors', async function () { - this.timeout(2500); - const inner$ = helper.padInner$; - const chrome$ = helper.padChrome$; - - // override the confirm dialogue functioon - helper.padChrome$.window.confirm = () => true; - - // get the first text element out of the inner iframe - const $firstTextElement = inner$('div').first(); - - // Set some new text - const sentText = 'Hello'; - - // select this text element - $firstTextElement.sendkeys('{selectall}'); - $firstTextElement.sendkeys(sentText); - $firstTextElement.sendkeys('{rightarrow}'); - - // wait until we have the full value available - await helper.waitForPromise( - () => inner$('div span').first().attr('class').indexOf('author') !== -1); - - // IE hates you if you don't give focus to the inner frame bevore you do a clearAuthorship - inner$('div').first().trigger('focus'); - - // get the clear authorship colors button and click it - const $clearauthorshipcolorsButton = chrome$('.buttonicon-clearauthorship'); - $clearauthorshipcolorsButton.trigger('click'); - - // does the first div include an author class? - const hasAuthorClass = inner$('div').first().attr('class').indexOf('author') !== -1; - expect(hasAuthorClass).to.be(false); - - await helper.waitForPromise( - () => chrome$('div.disconnected').attr('class').indexOf('visible') === -1); - }); - - it("makes text clear authorship colors and checks it can't be undone", async function () { - this.timeout(1500); - const inner$ = helper.padInner$; - const chrome$ = helper.padChrome$; - - // override the confirm dialogue functioon - helper.padChrome$.window.confirm = () => true; - - // get the first text element out of the inner iframe - const $firstTextElement = inner$('div').first(); - - // Set some new text - const sentText = 'Hello'; - - // select this text element - $firstTextElement.sendkeys('{selectall}'); - $firstTextElement.sendkeys(sentText); - $firstTextElement.sendkeys('{rightarrow}'); - - // wait until we have the full value available - await helper.waitForPromise( - () => inner$('div span').first().attr('class').indexOf('author') !== -1); - - // IE hates you if you don't give focus to the inner frame bevore you do a clearAuthorship - inner$('div').first().trigger('focus'); - - // get the clear authorship colors button and click it - const $clearauthorshipcolorsButton = chrome$('.buttonicon-clearauthorship'); - $clearauthorshipcolorsButton.trigger('click'); - - // does the first div include an author class? - let hasAuthorClass = inner$('div').first().attr('class').indexOf('author') !== -1; - expect(hasAuthorClass).to.be(false); - - const e = new inner$.Event(helper.evtType); - e.ctrlKey = true; // Control key - e.which = 90; // z - inner$('#innerdocbody').trigger(e); // shouldn't od anything - - // does the first div include an author class? - hasAuthorClass = inner$('div').first().attr('class').indexOf('author') !== -1; - expect(hasAuthorClass).to.be(false); - - // get undo and redo buttons - const $undoButton = chrome$('.buttonicon-undo'); - - // click the button - $undoButton.trigger('click'); // shouldn't do anything - hasAuthorClass = inner$('div').first().attr('class').indexOf('author') !== -1; - expect(hasAuthorClass).to.be(false); - - await helper.waitForPromise( - () => chrome$('div.disconnected').attr('class').indexOf('visible') === -1); - }); - - // Test for https://github.com/ether/etherpad-lite/issues/5128 - it('clears authorship when first line has line attributes', async function () { - // override the confirm dialogue function - helper.padChrome$.window.confirm = () => true; - - // Make sure there is text with author info. The first line must have a line attribute. - await helper.clearPad(); - await helper.edit('Hello'); - helper.padChrome$('.buttonicon-insertunorderedlist').click(); - await helper.waitForPromise(() => helper.padInner$('[class*="author-"]').length > 0); - - const nCommits = helper.commits.length; - helper.padChrome$('.buttonicon-clearauthorship').click(); - await helper.waitForPromise(() => helper.padInner$('[class*="author-"]').length === 0); - - // Make sure the change was actually accepted by reloading the pad and looking for authorship. - // Before the pad can be reloaded the server might need some time to accept the change. - await helper.waitForPromise(() => helper.commits.length > nCommits); - await helper.aNewPad({id: padId}); - expect(helper.padInner$('[class*="author-"]').length).to.be(0); - }); -});