diff --git a/fonts/Allura-Regular.otf b/fonts/Allura-Regular.otf new file mode 100644 index 0000000..cad9a53 Binary files /dev/null and b/fonts/Allura-Regular.otf differ diff --git a/fonts/ArialTh.ttf b/fonts/ArialTh.ttf new file mode 100644 index 0000000..614f0af Binary files /dev/null and b/fonts/ArialTh.ttf differ diff --git a/fonts/Pacifico.ttf b/fonts/Pacifico.ttf new file mode 100644 index 0000000..6d47cdc Binary files /dev/null and b/fonts/Pacifico.ttf differ diff --git a/pages/dashboard-page.js b/pages/dashboard-page.js index 2b1bf3c..a9c8a72 100644 --- a/pages/dashboard-page.js +++ b/pages/dashboard-page.js @@ -72,10 +72,52 @@ exports.DashboardPage = class DashboardPage { this.projectOptionsMenuButton = page.locator( 'a[data-test="project-options"] svg[class="icon-actions"]' ); - this.projectsSidebarItem = page.locator('li[class="recent-projects "]'); + this.projectsSidebarItem = page.locator('li:has-text("Projects")'); + this.draftsSidebarItem = page.locator('li:has-text("Drafts")'); + this.fontsSidebarItem = page.locator('li:has-text("Fonts")'); this.pinnedProjectsSidebarItem = page.locator( 'div[data-test="pinned-projects"]' ); + this.searchInput = page.locator("#search-input"); + this.uploadFontSelector = page.locator("#font-upload"); + this.uploadFontButton = page.locator('button:has-text("Upload")'); + this.fontNameTableCell = page.locator( + 'div[class="font-item table-row"] div[class="table-field family"]' + ); + this.fontStyleTableCell = page.locator( + 'div[class="font-item table-row"] div[class="table-field variants"]' + ); + this.fontOptionsMenuButton = page.locator( + 'div[class="table-field options"] svg[class="icon-actions"]' + ); + this.editFontMenuItem = page.locator('a[data-test="font-edit"]'); + this.deleteFontMenuItem = page.locator('a[data-test="font-delete"]'); + this.deleteFontButton = page.locator('input[value="Delete"]'); + this.fontsTablePlaceholder = page.locator( + 'div[class="fonts-placeholder"] div[class="label"]' + ); + this.fontNameInput = page.locator( + 'div[class="font-item table-row"] input[type="text"]' + ); + this.saveFontButton = page.locator('button:has-text("Save")'); + + this.searchFontInput = page.locator("input[placeholder='Search font']"); + + this.teamSelector = page.locator("div[class='current-team']"); + + this.createNewTeamMenuItem = page.locator( + "li[data-test='create-new-team']" + ); + + this.teamNameInput = page.locator("#name"); + + this.createNewTeamButton = page.locator("input[value='Create new team']"); + this.teamMenuItem = page.locator("li[class='team-name']"); + this.teamOptionsMenuButton = page.locator( + 'div[class="switch-options"] svg[class="icon-actions"]' + ); + this.deleteTeamMenuItem = page.locator('li[data-test="delete-team"]'); + this.deleteTeamButton = page.locator('input[value="Delete team"]'); } async isHeaderDisplayed(title) { @@ -165,7 +207,7 @@ exports.DashboardPage = class DashboardPage { await this.renameFileMenuItem.click(); await this.fileNameInput.type(newFileName); await this.page.keyboard.press("Enter"); - await expect(this.fileNameTitle).toHaveText(newFileName); + await this.isFileNameDisplayed(newFileName); } async renameFileViaOptionsIcon(newFileName) { @@ -175,7 +217,11 @@ exports.DashboardPage = class DashboardPage { await this.renameFileMenuItem.click(); await this.fileNameInput.type(newFileName); await this.page.keyboard.press("Enter"); - await expect(this.fileNameTitle).toHaveText(newFileName); + await this.isFileNameDisplayed(newFileName); + } + + async isFileNameDisplayed(fileName) { + await expect(this.fileNameTitle).toHaveText(fileName); } async duplicateFileViaRightclick() { @@ -311,6 +357,12 @@ exports.DashboardPage = class DashboardPage { case "Projects": await this.projectsSidebarItem.click(); break; + case "Drafts": + await this.draftsSidebarItem.click(); + break; + case "Fonts": + await this.fontsSidebarItem.click(); + break; } } async clickPinUnpinProjectButton() { @@ -323,4 +375,114 @@ exports.DashboardPage = class DashboardPage { async checkPinnedProjectsSidebarItem(text) { await expect(this.pinnedProjectsSidebarItem).toHaveText(text); } + + async search(text) { + await this.searchInput.type(text); + } + + async uploadFont(filePath) { + await this.uploadFontSelector.setInputFiles(filePath); + await this.uploadFontButton.click(); + await expect(this.uploadFontButton).not.toBeVisible(); + } + + async isFontUploaded(fontName, fontStyle) { + await expect(this.fontNameTableCell).toHaveText(fontName); + await expect(this.fontStyleTableCell).toHaveText(fontStyle); + } + + async deleteFont() { + await this.fontOptionsMenuButton.click(); + await this.deleteFontMenuItem.click(); + await this.deleteFontButton.click(); + } + + async deleteFonts() { + for (const el of await this.fontOptionsMenuButton.elementHandles()) { + await el.click(); + await this.deleteFontMenuItem.click(); + await this.deleteFontButton.click(); + } + } + + async deleteFontsIfExist() { + const fontRecords = await this.page.$$('div[class="font-item table-row"]'); + if (fontRecords) await this.deleteFonts(); + } + + async isFontsTablePlaceholderDisplayed(text) { + await expect(this.fontsTablePlaceholder).toHaveText(text); + } + + async editFont(newFontName) { + await this.fontOptionsMenuButton.click(); + await this.editFontMenuItem.click(); + await this.clearInput(this.fontNameInput); + await this.fontNameInput.type(newFontName); + await this.saveFontButton.click(); + await expect(this.fontNameTableCell).toHaveText(newFontName); + } + + async clearInput(input) { + await input.click(); + let text = await input.inputValue(); + for (let i = 0; i <= text.length; i++) { + await this.page.keyboard.press("Backspace"); + } + } + + async searchFont(fontName) { + await this.searchFontInput.type(fontName); + await expect(this.fontNameTableCell).toHaveText(fontName); + await expect(this.fontNameTableCell).toHaveCount(1); + } + + async createTeam(teamName) { + await this.teamSelector.click(); + await this.createNewTeamMenuItem.click(); + await this.teamNameInput.fill(teamName); + await this.createNewTeamButton.click(); + } + + async isTeamSelected(teamName) { + await expect(this.teamSelector).toHaveText(teamName); + } + + async deleteTeam(teamName) { + await this.teamSelector.click(); + for (const el of await this.teamMenuItem.elementHandles()) { + const text = (await el.innerText()).valueOf(); + if (text.includes(teamName)) { + await el.click(); + await this.teamOptionsMenuButton.click(); + await this.deleteTeamMenuItem.click(); + await this.deleteTeamButton.click(); + await expect(this.teamSelector).toHaveText("Your Penpot"); + } + } + } + + async deleteTeamsIfExist() { + await this.teamSelector.click(); + for (const el of await this.teamMenuItem.elementHandles()) { + const text = (await el.innerText()).valueOf(); + if (!text.includes("Your Penpot")) { + await el.click(); + await this.teamOptionsMenuButton.click(); + await this.deleteTeamMenuItem.click(); + await this.deleteTeamButton.click(); + await expect(this.teamSelector).toHaveText("Your Penpot"); + await this.teamSelector.click(); + } + } + await this.teamSelector.click(); + } + + async isTeamDeleted(teamName) { + await this.teamSelector.click(); + for (const el of await this.teamMenuItem.elementHandles()) { + const text = (await el.innerText()).valueOf(); + expect(text).not.toEqual(teamName); + } + } }; diff --git a/pages/main-page.js b/pages/main-page.js index 1cbd465..074faea 100644 --- a/pages/main-page.js +++ b/pages/main-page.js @@ -1,5 +1,4 @@ const { expect } = require("@playwright/test"); -const viewportLocator = 'div[class="viewport"]'; exports.MainPage = class MainPage { /** * @param {import('@playwright/test').Page} page @@ -18,7 +17,7 @@ exports.MainPage = class MainPage { this.textbox = page.locator( 'div[role="textbox"] div[contenteditable="true"]' ); - this.viewport = page.locator(viewportLocator); + this.viewport = page.locator('div[class="viewport"]'); this.savedChangesIcon = page.locator('div[class="saved"]'); this.pencilBoxButton = page.locator('div[class="main-icon"]'); } @@ -43,8 +42,8 @@ exports.MainPage = class MainPage { await this.textbox.fill(text); } - async uploadImage(imageUrl) { - await this.uploadImageSelector.setInputFiles(imageUrl); + async uploadImage(filePath) { + await this.uploadImageSelector.setInputFiles(filePath); } async clickCreateCurveButton() { diff --git a/tests/dashboard.spec.js b/tests/dashboard-files.spec.js similarity index 92% rename from tests/dashboard.spec.js rename to tests/dashboard-files.spec.js index bfadddb..b6af005 100644 --- a/tests/dashboard.spec.js +++ b/tests/dashboard-files.spec.js @@ -389,3 +389,30 @@ dashboardTest("Delete project via Options icon", async ({ page }) => { await dashboardPage.deleteProjectViaOptionsIcon(); await dashboardPage.isProjectTitleDisplayed("Drafts"); }); + +dashboardTest("Search file (from Drafts)", async ({ page }) => { + const dashboardPage = new DashboardPage(page); + await dashboardPage.createFileViaPlaceholder(); + const mainPage = new MainPage(page); + await mainPage.clickPencilBoxButton(); + await dashboardPage.renameFileViaRightclick("qwe"); + await dashboardPage.clickSidebarItem("Drafts"); + await dashboardPage.search("qwe"); + await dashboardPage.isHeaderDisplayed("Search results"); + await dashboardPage.isFileNameDisplayed("qwe"); +}); + +dashboardTest("Search file (from Projects)", async ({ page }) => { + const dashboardPage = new DashboardPage(page); + await dashboardPage.clickAddProjectButton(); + await dashboardPage.setProjectName("TestProject"); + await dashboardPage.isProjectTitleDisplayed("TestProject"); + await dashboardPage.createFileViaPlaceholder(); + const mainPage = new MainPage(page); + await mainPage.clickPencilBoxButton(); + await dashboardPage.renameFileViaRightclick("qaz"); + await dashboardPage.clickSidebarItem("Projects"); + await dashboardPage.search("qaz"); + await dashboardPage.isHeaderDisplayed("Search results"); + await dashboardPage.isFileNameDisplayed("qaz"); +}); diff --git a/tests/dashboard-fonts.spec.js b/tests/dashboard-fonts.spec.js new file mode 100644 index 0000000..a14f79d --- /dev/null +++ b/tests/dashboard-fonts.spec.js @@ -0,0 +1,43 @@ +const { dashboardTest } = require("../fixtures"); +const { DashboardPage } = require("../pages/dashboard-page"); +const { test } = require("@playwright/test"); + +test.beforeEach(async ({ page }) => { + const dashboardPage = new DashboardPage(page); + await dashboardPage.clickSidebarItem("Fonts"); + await dashboardPage.deleteFontsIfExist(); +}); + +dashboardTest("Upload single font", async ({ page }) => { + const dashboardPage = new DashboardPage(page); + await dashboardPage.clickSidebarItem("Fonts"); + await dashboardPage.uploadFont("fonts/Pacifico.ttf"); + await dashboardPage.isFontUploaded("Pacifico", "Regular"); +}); + +dashboardTest("Search font", async ({ page }) => { + const dashboardPage = new DashboardPage(page); + await dashboardPage.clickSidebarItem("Fonts"); + await dashboardPage.uploadFont("fonts/ArialTh.ttf"); + await dashboardPage.uploadFont("fonts/Allura-Regular.otf"); + await dashboardPage.searchFont("Arial Th"); +}); + +dashboardTest("Edit font", async ({ page }) => { + const dashboardPage = new DashboardPage(page); + await dashboardPage.clickSidebarItem("Fonts"); + await dashboardPage.uploadFont("fonts/Allura-Regular.otf"); + await dashboardPage.isFontUploaded("Allura", "Regular"); + await dashboardPage.editFont("New Test Font"); +}); + +dashboardTest("Delete font", async ({ page }) => { + const dashboardPage = new DashboardPage(page); + await dashboardPage.clickSidebarItem("Fonts"); + await dashboardPage.uploadFont("fonts/Pacifico.ttf"); + await dashboardPage.isFontUploaded("Pacifico", "Regular"); + await dashboardPage.deleteFont(); + await dashboardPage.isFontsTablePlaceholderDisplayed( + "You still have no custom fonts installed." + ); +}); diff --git a/tests/dashboard-teams.spec.js b/tests/dashboard-teams.spec.js new file mode 100644 index 0000000..25e497a --- /dev/null +++ b/tests/dashboard-teams.spec.js @@ -0,0 +1,22 @@ +const { dashboardTest } = require("../fixtures"); +const { DashboardPage } = require("../pages/dashboard-page"); +const { test } = require("@playwright/test"); + +test.beforeEach(async ({ page }) => { + const dashboardPage = new DashboardPage(page); + await dashboardPage.deleteTeamsIfExist(); +}); + +dashboardTest("Create a team", async ({ page }) => { + const dashboardPage = new DashboardPage(page); + await dashboardPage.createTeam("New Test Team"); + await dashboardPage.isTeamSelected("New Test Team"); +}); + +dashboardTest("Delete a team", async ({ page }) => { + const dashboardPage = new DashboardPage(page); + await dashboardPage.createTeam("QA Team"); + await dashboardPage.isTeamSelected("QA Team"); + await dashboardPage.deleteTeam("QA Team"); + await dashboardPage.isTeamDeleted("QA Team"); +});