mirror of
https://github.com/ether/etherpad-lite.git
synced 2025-05-07 15:47:12 -04:00
Added playwright tests. (#6212)
* Added playwright tests. * Added clear authorship color. * Ported enter ts. * Ported more tests. * Commented helper tests. * Fixed admin tests. * Fixed. * Fixed admin pages not there. * Fixed waiting. * Upload playwright report. * Remove saucelabs * Fixed waiting. * Fixed upload artifact. * Also install deps. * Added retry mechanism. * Added timeout for restart etherpad server. * Fixed tests. * Added frontend playwright tests.
This commit is contained in:
parent
db46ffb63b
commit
c2699e4528
40 changed files with 1568 additions and 1285 deletions
32
src/tests/frontend-new/helper/adminhelper.ts
Normal file
32
src/tests/frontend-new/helper/adminhelper.ts
Normal file
|
@ -0,0 +1,32 @@
|
|||
import {expect, Page} from "@playwright/test";
|
||||
|
||||
export const loginToAdmin = async (page: Page, username: string, password: string) => {
|
||||
|
||||
await page.goto('http://localhost:9001/admin/');
|
||||
|
||||
await page.waitForSelector('input[name="username"]');
|
||||
await page.fill('input[name="username"]', username);
|
||||
await page.fill('input[name="password"]', password);
|
||||
await page.click('input[type="button"]');
|
||||
}
|
||||
|
||||
|
||||
export const saveSettings = async (page: Page) => {
|
||||
// Click save
|
||||
await page.locator('.settings-button-bar').locator('button').first().click()
|
||||
await page.waitForSelector('.ToastRootSuccess')
|
||||
}
|
||||
|
||||
export const restartEtherpad = async (page: Page) => {
|
||||
// Click restart
|
||||
const restartButton = page.locator('.settings-button-bar').locator('.settingsButton').nth(1)
|
||||
const settings = page.locator('.settings');
|
||||
await expect(settings).not.toBeEmpty();
|
||||
await expect(restartButton).toBeVisible()
|
||||
await page.locator('.settings-button-bar')
|
||||
.locator('.settingsButton')
|
||||
.nth(1)
|
||||
.click()
|
||||
await page.waitForTimeout(500)
|
||||
await page.waitForSelector('.settings')
|
||||
}
|
155
src/tests/frontend-new/helper/padHelper.ts
Normal file
155
src/tests/frontend-new/helper/padHelper.ts
Normal file
|
@ -0,0 +1,155 @@
|
|||
import {Frame, Locator, Page} from "@playwright/test";
|
||||
import {MapArrayType} from "../../../node/types/MapType";
|
||||
import {randomInt} from "node:crypto";
|
||||
|
||||
export const getPadOuter = async (page: Page): Promise<Frame> => {
|
||||
return page.frame('ace_outer')!;
|
||||
}
|
||||
|
||||
export const getPadBody = async (page: Page): Promise<Locator> => {
|
||||
return page.frame('ace_inner')!.locator('#innerdocbody')
|
||||
}
|
||||
|
||||
export const selectAllText = async (page: Page) => {
|
||||
await page.keyboard.down('Control');
|
||||
await page.keyboard.press('A');
|
||||
await page.keyboard.up('Control');
|
||||
}
|
||||
|
||||
export const toggleUserList = async (page: Page) => {
|
||||
await page.locator("button[data-l10n-id='pad.toolbar.showusers.title']").click()
|
||||
}
|
||||
|
||||
export const setUserName = async (page: Page, userName: string) => {
|
||||
await page.waitForSelector('[class="popup popup-show"]')
|
||||
await page.click("input[data-l10n-id='pad.userlist.entername']");
|
||||
await page.keyboard.type(userName);
|
||||
}
|
||||
|
||||
|
||||
export const showChat = async (page: Page) => {
|
||||
const chatIcon = page.locator("#chaticon")
|
||||
const classes = await chatIcon.getAttribute('class')
|
||||
if (classes && !classes.includes('visible')) return
|
||||
await chatIcon.click()
|
||||
await page.waitForFunction(`!document.querySelector('#chaticon').classList.contains('visible')`)
|
||||
}
|
||||
|
||||
export const getCurrentChatMessageCount = async (page: Page) => {
|
||||
return await page.locator('#chattext').locator('p').count()
|
||||
}
|
||||
|
||||
export const getChatUserName = async (page: Page) => {
|
||||
return await page.locator('#chattext')
|
||||
.locator('p')
|
||||
.locator('b')
|
||||
.innerText()
|
||||
}
|
||||
|
||||
export const getChatMessage = async (page: Page) => {
|
||||
return (await page.locator('#chattext')
|
||||
.locator('p')
|
||||
.textContent({}))!
|
||||
.split(await getChatTime(page))[1]
|
||||
|
||||
}
|
||||
|
||||
|
||||
export const getChatTime = async (page: Page) => {
|
||||
return await page.locator('#chattext')
|
||||
.locator('p')
|
||||
.locator('.time')
|
||||
.innerText()
|
||||
}
|
||||
|
||||
export const sendChatMessage = async (page: Page, message: string) => {
|
||||
let currentChatCount = await getCurrentChatMessageCount(page)
|
||||
|
||||
const chatInput = page.locator('#chatinput')
|
||||
await chatInput.click()
|
||||
await page.keyboard.type(message)
|
||||
await page.keyboard.press('Enter')
|
||||
if(message === "") return
|
||||
await page.waitForFunction(`document.querySelector('#chattext').querySelectorAll('p').length >${currentChatCount}`)
|
||||
}
|
||||
|
||||
export const isChatBoxShown = async (page: Page):Promise<boolean> => {
|
||||
const classes = await page.locator('#chatbox').getAttribute('class')
|
||||
return classes !==null && classes.includes('visible')
|
||||
}
|
||||
|
||||
export const isChatBoxSticky = async (page: Page):Promise<boolean> => {
|
||||
const classes = await page.locator('#chatbox').getAttribute('class')
|
||||
console.log('Chat', classes && classes.includes('stickyChat'))
|
||||
return classes !==null && classes.includes('stickyChat')
|
||||
}
|
||||
|
||||
export const hideChat = async (page: Page) => {
|
||||
if(!await isChatBoxShown(page)|| await isChatBoxSticky(page)) return
|
||||
await page.locator('#titlecross').click()
|
||||
await page.waitForFunction(`!document.querySelector('#chatbox').classList.contains('stickyChat')`)
|
||||
|
||||
}
|
||||
|
||||
export const enableStickyChatviaIcon = async (page: Page) => {
|
||||
if(await isChatBoxSticky(page)) return
|
||||
await page.locator('#titlesticky').click()
|
||||
await page.waitForFunction(`document.querySelector('#chatbox').classList.contains('stickyChat')`)
|
||||
}
|
||||
|
||||
export const disableStickyChatviaIcon = async (page: Page) => {
|
||||
if(!await isChatBoxSticky(page)) return
|
||||
await page.locator('#titlecross').click()
|
||||
await page.waitForFunction(`!document.querySelector('#chatbox').classList.contains('stickyChat')`)
|
||||
}
|
||||
|
||||
|
||||
export const appendQueryParams = async (page: Page, queryParameters: MapArrayType<string>) => {
|
||||
const searchParams = new URLSearchParams(page.url().split('?')[1]);
|
||||
Object.keys(queryParameters).forEach((key) => {
|
||||
searchParams.append(key, queryParameters[key]);
|
||||
});
|
||||
await page.goto(page.url()+"?"+ searchParams.toString());
|
||||
await page.waitForSelector('iframe[name="ace_outer"]');
|
||||
}
|
||||
|
||||
export const goToNewPad = async (page: Page) => {
|
||||
// create a new pad before each test run
|
||||
const padId = "FRONTEND_TESTS"+randomInt(0, 1000);
|
||||
await page.goto('http://localhost:9001/p/'+padId);
|
||||
await page.waitForSelector('iframe[name="ace_outer"]');
|
||||
return padId;
|
||||
}
|
||||
|
||||
export const goToPad = async (page: Page, padId: string) => {
|
||||
await page.goto('http://localhost:9001/p/'+padId);
|
||||
await page.waitForSelector('iframe[name="ace_outer"]');
|
||||
}
|
||||
|
||||
|
||||
export const clearPadContent = async (page: Page) => {
|
||||
await page.keyboard.down('Control');
|
||||
await page.keyboard.press('A');
|
||||
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()
|
||||
}
|
35
src/tests/frontend-new/helper/settingsHelper.ts
Normal file
35
src/tests/frontend-new/helper/settingsHelper.ts
Normal file
|
@ -0,0 +1,35 @@
|
|||
import {Page} from "@playwright/test";
|
||||
|
||||
export const isSettingsShown = async (page: Page) => {
|
||||
const classes = await page.locator('#settings').getAttribute('class')
|
||||
return classes && classes.includes('popup-show')
|
||||
}
|
||||
|
||||
|
||||
export const showSettings = async (page: Page) => {
|
||||
if(await isSettingsShown(page)) return
|
||||
await page.locator("button[data-l10n-id='pad.toolbar.settings.title']").click()
|
||||
await page.waitForFunction(`document.querySelector('#settings').classList.contains('popup-show')`)
|
||||
}
|
||||
|
||||
export const hideSettings = async (page: Page) => {
|
||||
if(!await isSettingsShown(page)) return
|
||||
await page.locator("button[data-l10n-id='pad.toolbar.settings.title']").click()
|
||||
await page.waitForFunction(`!document.querySelector('#settings').classList.contains('popup-show')`)
|
||||
}
|
||||
|
||||
export const enableStickyChatviaSettings = async (page: Page) => {
|
||||
const stickyChat = page.locator('#options-stickychat')
|
||||
const checked = await stickyChat.isChecked()
|
||||
if(checked) return
|
||||
await stickyChat.check({force: true})
|
||||
await page.waitForSelector('#options-stickychat:checked')
|
||||
}
|
||||
|
||||
export const disableStickyChat = async (page: Page) => {
|
||||
const stickyChat = page.locator('#options-stickychat')
|
||||
const checked = await stickyChat.isChecked()
|
||||
if(!checked) return
|
||||
await stickyChat.uncheck({force: true})
|
||||
await page.waitForSelector('#options-stickychat:not(:checked)')
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue