diff --git a/e2e-tests/base.test.ts b/e2e-tests/base.test.ts index 8afbb2507..d7af714e1 100644 --- a/e2e-tests/base.test.ts +++ b/e2e-tests/base.test.ts @@ -2,7 +2,16 @@ import { test, expect } from './myFixtures'; import packageInfo from '../package.json'; -import { showLoginPage, checkLogInOrNot, userFile, userFolder, userJson, createProjectValidation, createProjects, unstarProject, starProject, userValidation, signOut, showActiveUsers, searchProject, checkProjectName, checkNotification, goToProjectPage } from './common'; +import { + showLoginPage, checkLogInOrNot, userFile, + userFolder, userJson, createProjectValidation, + createProjects, unstarProject, starProject, + userValidation, signOut, showActiveUsers, + searchProject, checkProjectName, checkNotification, + goToProjectPage, exportProjects, archivedProjects, + unarchivedProjects, goToEditProject, changeAppLanguage, + projectTargetLanguage, userProfileValidaiton +} from './common'; const fs = require('fs'); const path = require('path'); @@ -38,20 +47,29 @@ test('If logged IN then logout and delete that user from the backend', async ({ const folder = await userFolder(window, userName, packageInfo, path) if (await checkLogInOrNot(window, expect)) { - expect(await window.locator('//*[@id="user-profile"]')).toBeVisible() - await window.locator('//*[@id="user-profile"]').click() - const currentUser = await window.textContent('[aria-label="userName"]') - expect(await window.locator('//*[@aria-label="signout"]')).toBeVisible() - await window.locator('//*[@aria-label="signout"]').click() - // projects page then logout and delete playwright user + // Check if user profile image is visible + const userProfileImage = window.locator('//*[@id="user-profile-image"]'); + expect(await userProfileImage.isVisible()).toBeTruthy(); + await userProfileImage.click(); + + // Get the current user's name + const currentUser = await window.textContent('[aria-label="userName"]'); + expect(currentUser).not.toBeNull(); + + // Check if signout button is visible + const signoutButton = window.locator('//*[@aria-label="signout"]'); + expect(await signoutButton.isVisible()).toBeTruthy(); + await signoutButton.click(); + + // If the current user matches and the folder exists, log out and delete the user if (currentUser.toLowerCase() === userName.toLowerCase() && await fs.existsSync(folder)) { - await showLoginPage(fs, folder, userName, json, file, window, expect) + await showLoginPage(fs, folder, userName, json, file, window, expect); } } else { - // loging page, if playwright user exist then reload app and remove - const existUser = json.some((item) => item.username.toLowerCase() === userName.toLowerCase()) + // On the login page, if the playwright user exists, reload the app and remove it + const existUser = json.some((item) => item.username.toLowerCase() === userName.toLowerCase()); if (existUser && await fs.existsSync(folder)) { - await showLoginPage(fs, folder, userName, json, file, window, expect) + await showLoginPage(fs, folder, userName, json, file, window, expect); } } @@ -63,8 +81,8 @@ test('Create a new user and login', async ({ userName }) => { await window.locator('//input[@placeholder="Username"]').fill(userName) await expect(window.locator('//button[@type="submit"]')).toBeVisible() await window.click('[type=submit]'); - const title = await window.locator('//h1[@aria-label="projects"]', { timeout: 10000 }).textContent(); - expect(title).toBe('Projects'); + const title = await window.locator('//*[@aria-label="projects"]').textContent(); + await expect(title).toBe('Projects'); }) @@ -80,15 +98,13 @@ test('Click New and Fill project page details to create a new project for text t await window.locator('//textarea[@id="project_description"]').fill('test description') await expect(window.locator('//input[@id="version_abbreviated"]')).toBeVisible() await window.locator('//input[@id="version_abbreviated"]').fill('ttp') - await expect(window.locator('//button[@id="open-advancesettings"]')).toBeVisible() - await window.locator('//button[@id="open-advancesettings"]').click() - await expect(window.locator('//div[@aria-label="custom-book"]')).toBeVisible() - await window.locator('//div[@aria-label="custom-book"]').click() + await expect(window.locator('//*[@id="open-advancesettings"]')).toBeVisible() + await window.locator('//*[@id="open-advancesettings"]').click() + await expect(window.locator('//*[@aria-label="custom-book"]')).toBeVisible() + await window.locator('//*[@aria-label="custom-book"]').click() await window.locator('//*[@aria-label="nt-Matthew"]').click() await window.locator('//*[@id="save-canon"]').click() await window.locator('//button[@aria-label="create"]').click() - const notifyMe = await window.textContent('//*[@id="__next"]/div/div[2]/div[2]/div/div') - await expect(notifyMe).toBe('New project created') const projectName = await window.innerText(`//div[@id="${textProject}"]`) await expect(projectName).toBe(textProject); }) @@ -226,13 +242,177 @@ test('Return to the projects from audio editor page', async () => { /* about the scribe */ test("About scribe Application and License", async () => { await window.locator('//*[@aria-label="about-button"]').click() - const developedby = await window.innerText('[aria-label=developed-by]'); + const developedby = await window.locator('[aria-label=developed-by]').textContent(); expect(developedby).toBe('Developed by Bridge Connectivity Solutions'); await window.click('[aria-label=license-button]'); await window.locator('//*[@aria-label="about-description"]').click() await window.click('[aria-label=close-about]'); - const title = await window.locator('//h1[@aria-label="projects"]', { timeout: 10000 }).textContent(); - expect(title).toBe('Projects'); + const title = await window.locator('//*[@aria-label="projects"]').textContent(); + await expect(title).toBe('Projects'); +}) + +/* exports project */ +test("Export text translation project in the Downloads folder", async ({ textProject }) => { + await exportProjects(window, expect, textProject) +}) + +test("Export the obs project in the Downloads folder", async ({ obsProject }) => { + await exportProjects(window, expect, obsProject) +}) + +test("Export the audio project in the Downloads folder", async ({ audioProject }) => { + await exportProjects(window, expect, audioProject) +}) + +/* archive and unarchive project */ +test("Archive text translation project", async ({ textProject }) => { + await archivedProjects(window, expect, textProject) +}) + +test("Restore text translation project from archived page", async ({ textProject }) => { + await unarchivedProjects(window, expect, textProject) +}) + +test("Archive obs project", async ({ obsProject }) => { + await archivedProjects(window, expect, obsProject) +}) + +test("Restore the obs project from archived page", async ({ obsProject }) => { + await unarchivedProjects(window, expect, obsProject) +}) + +test("Archive audio project", async ({ audioProject }) => { + await archivedProjects(window, expect, audioProject) +}) + +test("Restore the audio project from the archived page", async ({ audioProject }) => { + await unarchivedProjects(window, expect, audioProject) +}) + +/* Update/Edit the text translation project */ +test("Update/Edit text translation project of description and abbreviation", async ({ textProject }) => { + await goToEditProject(window, expect, textProject) + const description = await window.textContent('//textarea[@id="project_description"]') + await expect(description).toBe('test description') + await window.locator('//textarea[@id="project_description"]').fill('edit test version') + const editDescription = await window.textContent('//textarea[@id="project_description"]') + await expect(editDescription).toBe('edit test version') + await window.locator('input[name="version_abbreviated"]').fill('tvs') + await expect(window.locator('//*[@aria-label="save-edit-project"]')).toBeVisible() + await window.locator('//*[@aria-label="save-edit-project"]').click() + await window.waitForTimeout(3000) + const title = await window.textContent('[aria-label=projects]'); + expect(await title).toBe('Projects') +}) + +test("Update/Edit text translation project scope mark and luke", async ({ textProject }) => { + await goToEditProject(window, expect, textProject) + await expect(window.locator('//*[@id="open-advancesettings"]')).toBeVisible() + await window.locator('//*[@id="open-advancesettings"]').click() + await expect(window.locator('//*[@aria-label="custom-book"]')).toBeVisible() + await window.locator('//*[@aria-label="custom-book"]').click() + await window.locator('//*[@aria-label="nt-Mark"]').click() + await window.locator('//*[@aria-label="nt-Luke"]').click() + await window.locator('//*[@id="save-canon"]').click() + await expect(window.locator('//*[@aria-label="save-edit-project"]')).toBeVisible() + await window.locator('//*[@aria-label="save-edit-project"]').click() + await window.waitForTimeout(2500) + const title = await window.textContent('[aria-label=projects]'); + expect(await title).toBe('Projects') +}) + +test("Update/Edit text translation project scope custom book into NT", async ({ textProject }) => { + await goToEditProject(window, expect, textProject) + await expect(window.locator('//*[@id="open-advancesettings"]')).toBeVisible() + await window.locator('//*[@id="open-advancesettings"]').click() + await expect(window.locator('//*[@aria-label="new-testament"]')).toBeVisible() + await window.locator('//*[@aria-label="new-testament"]').click() + await window.locator('//button[contains(text(),"Ok")]').click() + await expect(window.locator('//*[@aria-label="save-edit-project"]')).toBeVisible() + await window.locator('//*[@aria-label="save-edit-project"]').click() + await window.waitForTimeout(3000) + const title = await window.textContent('[aria-label=projects]'); + expect(await title).toBe('Projects') +}) + +test("Update/Edit text transaltion project scope custom book genesis and exodus from OT", async ({ textProject }) => { + await goToEditProject(window, expect, textProject) + await expect(window.locator('//*[@id="open-advancesettings"]')).toBeVisible() + await window.locator('//*[@id="open-advancesettings"]').click() + await expect(window.locator('//*[@aria-label="custom-book"]')).toBeVisible() + await window.locator('//*[@aria-label="custom-book"]').click() + await window.locator('//*[@aria-label="ot-Genesis"]').click() + await window.locator('//*[@aria-label="ot-Exodus"]').click() + await window.locator('//*[@id="save-canon"]').click() + await expect(window.locator('//*[@aria-label="save-edit-project"]')).toBeVisible() + await window.locator('//*[@aria-label="save-edit-project"]').click() + await window.waitForTimeout(3000) + const title = await window.textContent('[aria-label=projects]'); + expect(await title).toBe('Projects') +}) + +test("Update/Edit text translation project license", async ({ textProject }) => { + await goToEditProject(window, expect, textProject) + await expect(window.locator('//*[@id="open-advancesettings"]')).toBeVisible() + await window.locator('//*[@id="open-advancesettings"]').click() + await window.getByRole('button', { name: 'CC BY-SA' }).click() + await window.getByRole('option', { name: 'CC BY', exact: true }).click() + await expect(window.locator('//*[@aria-label="save-edit-project"]')).toBeVisible() + await window.locator('//*[@aria-label="save-edit-project"]').click() + await window.waitForTimeout(3000) + const title = await window.textContent('[aria-label=projects]'); + expect(await title).toBe('Projects') +}) + +/* Changing text translation project target language */ +test("Changing text translation project language from English to Persian", async ({ textProject }) => { + await projectTargetLanguage(window, expect, textProject, "persian", "Persian (Farsi)") +}) + +test("Changing text translation project language from Persian to English", async ({ textProject }) => { + await projectTargetLanguage(window, expect, textProject, "english", "English") +}) + +/* updating user profile */ +test("Update user Profile", async () => { + await userProfileValidaiton(window, expect) + await expect(window.locator('input[name="given-name"]')).toBeVisible(); + await window.locator('input[name="given-name"]').fill("Bobby") + await expect(window.locator('input[name="family-name"]')).toBeVisible(); + await window.locator('input[name="family-name"]').fill("kumar") + await expect(window.locator('input[name="email"]')).toBeVisible(); + await window.locator('input[name="email"]').fill("kumar@gamil.com") + await expect(window.locator('input[name="organization"]')).toBeVisible(); + await window.locator('input[name="organization"]').fill("vidya foundation") + await expect(window.locator('input[name="selectedregion"]')).toBeVisible(); + await window.locator('input[name="selectedregion"]').fill("India") + expect(await window.locator('//*[@id="save-profile"]')).toBeVisible() + await window.locator('//*[@id="save-profile"]').click() + const snackbar = await window.locator('//*[@aria-label="snack-text"]').textContent() + expect(snackbar).toBe("Updated the Profile.") +}) + +/*changing app language english to hindi */ +test("App language change English to hindi", async () => { + await changeAppLanguage(window, expect, "English", "Hindi") + const snackbar = await window.locator('//*[@id="__next"]/div[2]/div/div').isVisible() + expect(await snackbar === true) + const textHindi = await window.locator('//*[@aria-label="projects"]').allTextContents() + expect(await textHindi[0]).toBe("प्रोफ़ाइल") +}) + +/*changing app language hindi to english */ +test("App language change Hindi to English", async () => { + expect(await window.locator('//*[@aria-label="projectList"]')).toBeVisible() + await window.locator('//*[@aria-label="projectList"]').click() + await window.waitForTimeout(2000) + const title = await window.textContent('[aria-label=projects]', { timeout: 10000 }); + expect(await title).toBe('प्रोजेक्ट्स') + await changeAppLanguage(window, expect, "Hindi", "English") + const snackbar = await window.locator('//*[@id="__next"]/div[2]/div/div').isVisible() + const profile = await window.locator('//*[@aria-label="projects"]').allTextContents() + expect(await profile[0]).toBe("Profile") + expect(await snackbar === true) }) /*signing out */ @@ -249,8 +429,8 @@ test("Click the view users button, log in with playwright user, and sign out", a if (await div.nth(i).textContent() === userName.toLowerCase()) { await div.nth(i).click() await window.waitForTimeout(1000) - const title = await window.locator('//h1[@aria-label="projects"]', { timeout: 10000 }).textContent(); - expect(title).toBe('Projects') + const title = await window.locator('//*[@aria-label="projects"]').textContent(); + await expect(title).toBe('Projects') await signOut(window, expect) break } @@ -281,8 +461,8 @@ test("Delete the user from the active tab and check in the archived tab", async break } } - const title = await window.locator('//h1[@aria-label="projects"]', { timeout: 10000 }).textContent(); - expect(title).toBe('Projects') + const title = await window.locator('//*[@aria-label="projects"]').textContent(); + await expect(title).toBe('Projects') }) /* logout and delete the playwright user */ @@ -293,8 +473,8 @@ test("Logout and delete that playwright user from the backend", async ({ userNam const file = await userFile(window, packageInfo, path) // user folde name const folder = await userFolder(window, userName, packageInfo, path) - expect(await window.locator('//*[@id="user-profile"]')).toBeVisible() - await window.locator('//*[@id="user-profile"]').click() + expect(await window.locator('//*[@id="user-profile-image"]')).toBeVisible() + await window.locator('//*[@id="user-profile-image"]').click() const currentUser = await window.textContent('[aria-label="userName"]') expect(await window.locator('//*[@aria-label="signout"]')).toBeVisible() await window.locator('//*[@aria-label="signout"]').click() diff --git a/e2e-tests/common.js b/e2e-tests/common.js index f225f96a7..9fca92042 100644 --- a/e2e-tests/common.js +++ b/e2e-tests/common.js @@ -1,11 +1,18 @@ export const checkLogInOrNot = async (window, expect) => { await window.waitForSelector('//*[@id="__next"]/div', '//*[@id="__next"]/div[1]', { timeout: 5000 }) - const textVisble = await window.locator('//h1[@aria-label="projects"]', { timeout: 5000 }).isVisible() + const textVisble = await window.locator('//*[@aria-label="projects"]').isVisible() if (textVisble) { - const title = await window.locator('//h1[@aria-label="projects"]').textContent() - await expect(title).toBe('Projects') - + // If title is "Projects" (english) or Not(other language) visible in project list page, + const title = await window.locator('//*[@aria-label="projects"]').textContent() + if(await title === "Projects"){ + //expecting "Projects" in english + await expect(title).toBe("Projects") + }else{ + //expecting "Projects" in Other langauage + await expect(title).not.toBe('Projects') + } } else { + // If 'projects' is not visible, check the 'welcome' element const welcome = await window.locator('//h2[@aria-label="welcome"]', {timeout:5000}).textContent() await expect(welcome).toBe("Welcome!") await window.reload() @@ -13,6 +20,7 @@ export const checkLogInOrNot = async (window, expect) => { return textVisble; } +// Retrieves and parses a JSON file containing user information export const userJson = async (window, packageInfo, fs, path) => { const newpath = await window.evaluate(() => Object.assign({}, window.localStorage)) const file = path.join(newpath.userPath, packageInfo.name, 'users', 'users.json'); @@ -20,16 +28,19 @@ export const userJson = async (window, packageInfo, fs, path) => { return JSON.parse(data); } +// Constructs the path to a user's folder. export const userFolder = async (window, userName, packageInfo, path) => { const newpath = await window.evaluate(() => Object.assign({}, window.localStorage)) return path.join(newpath.userPath, packageInfo.name, 'users', userName.toLowerCase()) } +// Constructs the path to the users' JSON file. export const userFile = async (window, packageInfo, path) => { const newpath = await window.evaluate(() => Object.assign({}, window.localStorage)) return path.join(newpath.userPath, packageInfo.name, 'users', 'users.json'); } +// Removes a user's directory and updates the users' JSON file export const removeFolderAndFile = async (fs, folder, userName, json, file) => { fs.rmSync(folder, { recursive: true, force: true }) const filtered = json.filter((item) => @@ -38,7 +49,7 @@ export const removeFolderAndFile = async (fs, folder, userName, json, file) => { return await fs.writeFileSync(file, JSON.stringify(filtered)) } -// display welcome page +// Displays the welcome page after removing a user's folder. export const showLoginPage = async (fs, folder, userName, json, file, window, expect) => { await removeFolderAndFile(fs, folder, userName, json, file) const welcome = await window.locator('//h2[@aria-label="welcome"]', {timeout:5000}).textContent() @@ -46,7 +57,7 @@ export const showLoginPage = async (fs, folder, userName, json, file, window, ex await window.reload() } -// user validation +// Performs user validation checks. export const userValidation = async (window, expect) => { expect(await window.locator('//*[@aria-label="create-new-account"]')).toBeVisible() await window.locator('//*[@aria-label="create-new-account"]').click() @@ -55,21 +66,20 @@ export const userValidation = async (window, expect) => { await expect(window.locator('//button[@type="submit"]')).toBeVisible() await window.click('[type=submit]'); const lengthError = await window.locator('//*[@id="show-error"]') - expect(await lengthError === true) expect(await lengthError.textContent()).toBe('The input has to be between 3 and 15 characters long') } -// project creation validation +// Performs project creation validation checks. export const createProjectValidation = async (window, expect) => { await window.locator('//button[@aria-label="create"]').click() - const snackbar = await window.textContent('//*[@id="__next"]/div/div[2]/div[2]/div/div') - expect(await snackbar).toBe('Fill all the fields') - const title = await window.locator('//h1[@aria-label="projects"]').textContent(); + const snackbar = await window.locator('//*[@aria-label="snack-text"]').textContent() + await expect(snackbar).toBe('Fill all the fields') + const title = await window.locator('//*[@aria-label="projects"]').textContent(); await expect(title).toBe('New Project'); await window.waitForTimeout(3000) } -/* function for creating a project for obs and audio */ +/* Creates a project with a given name, type, description, and abbreviation. */ export const createProjects = async (window, expect, projectname, type, description, abb) => { await expect(window.locator('//a[@aria-label="new"]')).toBeVisible() await window.locator('//a[@aria-label="new"]').click() @@ -91,56 +101,40 @@ export const createProjects = async (window, expect, projectname, type, descript await expect(projectName).toBe(projectname); } -// star the project -export const starProject = async (window, expect, projectname) => { - await expect(window.locator('//*[@id="projects-list"]')).toBeVisible() - const table = window.locator('//*[@id="projects-list"]') - const body = table.locator('//*[@id="projects-list-unstar"]') - const starBody = table.locator('//*[@id="projects-list-star"]') +// Stars or unstars a project +export const starUnstar = async (window, expect, name, clickStar) => { + await expect(window.locator('//table[@id="projects-list"]')).toBeVisible() + const table = window.locator('//table[@id="projects-list"]') + const body = table.locator('//*[@id="projects-list-body"]') const rows = await body.locator('tr') for (let i = 0; i < await rows.count(); i++) { const row = await rows.nth(i); const tds = await row.locator('td'); - if (await tds.nth(1).textContent() === projectname) { - expect(await tds.first().locator('[aria-label=unstar-project]')).toBeVisible() - await tds.first().locator('[aria-label=unstar-project]').click() - expect(await rows.count()).toBe(2) - const starRows = await starBody.locator('tr') - const starProjectName = await starRows.locator("td").nth(1).innerText() - expect(await starProjectName).toBe(projectname) - expect(await starRows.count()).toBe(1) + if (await tds.nth(1).textContent() === name) { + expect(await tds.first().locator(`[aria-label=${clickStar}]`)).toBeVisible() + await tds.first().locator(`[aria-label=${clickStar}]`).click() + await window.waitForTimeout(500) break } } } -// unstar the project +// Stars a project +export const starProject = async (window, expect, projectname) => { + await starUnstar(window, expect, projectname, "star-project") +} + +// Untars a project export const unstarProject = async (window, expect, projectname) => { - await expect(window.locator('//*[@id="projects-list"]')).toBeVisible() - const table = window.locator('//*[@id="projects-list"]') - const body = table.locator('//*[@id="projects-list-star"]') - const rows = await body.locator('tr') - for (let i = 0; i < await rows.count(); i++) { - const row = await rows.nth(i); - const tds = await row.locator('td'); - if (await tds.nth(1).textContent() === projectname) { - expect(await tds.first().locator('[aria-label=star-project]')).toBeVisible() - await tds.first().locator('[aria-label=star-project]').click() - const unstarBody = table.locator('//*[@id="projects-list-unstar"]') - const unstarRows = await unstarBody.locator('tr') - expect(await rows.count()).toBe(0) - expect(await unstarRows.count()).toBe(3) - break; - } - } + await starUnstar(window, expect, projectname, "unstar-project") } -// search projects +// Searches for a project with a given name. export const searchProject = async (window, expect, projectName, searchtext) => { await window.waitForTimeout(500) await expect(window.locator('//input[@id="search_box"]')).toBeVisible() await window.locator('//input[@id="search_box"]').fill(searchtext) - const projectname = await window.innerText(`//*[@id="${projectName}"]`); + const projectname = await window.locator(`//*[@id="${projectName}"]`).textContent() await expect(projectname).toBe(projectName); } @@ -148,7 +142,7 @@ export const searchProject = async (window, expect, projectName, searchtext) => export const checkProjectName = async (window, expect, name) => { await expect(window.locator('//*[@id="projects-list"]')).toBeVisible() const table = window.locator('//*[@id="projects-list"]') - const body = table.locator('//*[@id="projects-list-unstar"]') + const body = table.locator('//*[@id="projects-list-body"]') const rows = await body.locator('tr') for (let i = 0; i < await rows.count(); i++) { const row = await rows.nth(i); @@ -159,31 +153,167 @@ export const checkProjectName = async (window, expect, name) => { } } await window.waitForTimeout(1000) - const projectname = await window.locator('[aria-label=editor-project-name]', { timeout: 10000 }).textContent() - expect(projectname).toBe(name); + await window.waitForSelector('[aria-label=editor-project-name]',{ timeout: 120000 }) + const projectname = await window.locator('[aria-label=editor-project-name]').textContent() + expect(await projectname).toBe(name); } -// check notification +// Checks for notifications. export const checkNotification = async (window, expect) => { + await window.waitForSelector('//*[@aria-label="notification-button"]', {timeout : 5000}) await window.locator('//*[@aria-label="notification-button"]').click() - const title = await window.innerText('[aria-label=notification-title]'); - await expect(title).toBe('NOTIFICATIONS'); + await window.waitForTimeout(1000) + const title = await window.locator('[aria-label=notification-title]').textContent(); + await expect(title).toBe('Notifications'); await window.locator('//*[@aria-label="close-notification"]').click() } -// back button in editor page +// Navigates back to the project page from the editor export const goToProjectPage = async (window, expect) => { await expect(window.locator('//*[@id="back-button"]')).toBeVisible() await window.locator('//*[@id="back-button"]').click(); - const title = await window.locator('//h1[@aria-label="projects"]', { timeout: 10000 }).textContent(); - expect(title).toBe('Projects'); + const title = await window.locator('//*[@aria-label="projects"]').textContent(); + await expect(title).toBe('Projects'); await window.waitForTimeout(1000) } -// sing out +// Common function for interacting with tables. +export const commonFilterTable = async (window, expect, projectName, clickItem) => { + await expect(window.locator('//*[@id="projects-list"]')).toBeVisible() + const table = window.locator('//*[@id="projects-list"]') + const body = table.locator('//*[@id="projects-list-body"]') + const rows = await body.locator('tr') + for (let i = 0; i < await rows.count(); i++) { + const row = await rows.nth(i); + const tds = await row.locator('td'); + if (await tds.nth(1).textContent() === projectName) { + expect(await tds.last().locator('[aria-label="expand-project"]')).toBeVisible() + await tds.last().locator('[aria-label="expand-project"]').click() + await window.waitForTimeout(1000) + await window.locator('//*[@aria-label="menu-project"]').click() + await window.locator(`//*[@aria-label="${clickItem}"]`).click() + break + } + } +} + +// Exports a project to a specified location +export const exportProjects = async (window, expect, projectname) => { + const newpath = await window.evaluate(() => Object.assign({}, window.localStorage)) + const userpath = newpath.userPath.split(".")[0] + await commonFilterTable(window, expect, projectname, "export-project") + await expect(window.locator('input[name="location"]')).toBeVisible() + await window.locator('input[name="location"]').fill(`${userpath}/Downloads`) + await window.locator('//*[@aria-label="export-projects"]').click() + await window.waitForTimeout(2000) + const snackText = await window.locator('//*[@aria-label="snack-text"]').textContent() + await expect(snackText).toBe("Exported Successfully") + await window.locator('[aria-label=arrow-up]').click() +} + + +// Moves a project to the archived projects section +export const archivedProjects = async (window, expect, projectname) => { + await commonFilterTable(window, expect, projectname, "archive-restore-project") + await window.locator('//*[@aria-label="archived-projects"]').click() + const archiveTitle = await window.locator('//*[@aria-label="projects"]').textContent() + await expect(archiveTitle).toBe("Archived projects") + const projectName = await window.innerText(`//div[@id="${projectname}"]`) + await expect(projectName).toBe(projectname); + await window.locator('//*[@aria-label="active-projects"]').click() + const projectTitle = await window.locator('//*[@aria-label="projects"]').textContent() + await expect(projectTitle).toBe('Projects'); +} + +// Moves a project back from archived to active projects. +export const unarchivedProjects = async (window, expect, projectname) => { + await window.locator('//*[@aria-label="archived-projects"]').click() + await commonFilterTable(window, expect, projectname, "archive-restore-project") + const archiveTitle = await window.locator('//*[@aria-label="projects"]').textContent() + await expect(archiveTitle).toBe("Archived projects") + await window.locator('//*[@aria-label="active-projects"]').click() + const projectName = await window.innerText(`//div[@id="${projectname}"]`) + await expect(projectName).toBe(projectname); + const projectTitle = await window.locator('//*[@aria-label="projects"]').textContent() + await expect(projectTitle).toBe('Projects'); +} + +// Navigates to the project editing page. +export const goToEditProject = async (window, expect, projectName) => { + await commonFilterTable(window, expect, projectName, "edit-project") + const editTitle = await window.locator('//*[@aria-label="projects"]').textContent() + await expect(editTitle).toBe('Edit Project'); +} +// change project target language +export const projectTargetLanguage = async (window, expect, projectName, searchLangauge, selectLanguage) => { + await goToEditProject(window, expect, projectName) + expect(await window.locator('//*[@aria-label="custom-dropdown"]')).toBeVisible() + await window.locator('//*[@aria-label="custom-dropdown"]').fill(searchLangauge) + await window.locator(`//*[@aria-label="${selectLanguage}"]`).click() + await expect(window.locator('//*[@aria-label="save-edit-project"]')).toBeVisible() + await window.locator('//*[@aria-label="save-edit-project"]').click() + await window.waitForTimeout(2000) + await expect(window.locator('//*[@id="projects-list"]')).toBeVisible() + const table = window.locator('//*[@id="projects-list"]') + const body = table.locator('//*[@id="projects-list-body"]') + const rows = body.locator('tr') + for (let i = 0; i < await rows.count(); i++) { + const row = await rows.nth(i); + const tds = await row.locator('td'); + if (await tds.nth(1).textContent() === projectName) { + // expecting language + expect(await tds.nth(2).textContent()).toBe(selectLanguage) + } + } + const title = await window.textContent('[aria-label=projects]', { timeout: 10000 }); + expect(title).toBe('Projects'); +} + +// Performs user profile validation checks. +export const userProfileValidaiton = async(window, expect) => { + expect(await window.locator('//*[@id="user-profile-image"]')).toBeVisible() + await window.locator('//*[@id="user-profile-image"]').click() + expect(await window.locator('//*[@aria-label="user-profile"]')).toBeVisible() + await window.locator('//*[@aria-label="user-profile"]').click() + await expect(window.locator('input[name="given-name"]')).toBeVisible(); + await window.locator('input[name="given-name"]').fill("b") + await expect(window.locator('input[name="family-name"]')).toBeVisible(); + await window.locator('input[name="family-name"]').fill("k") + await expect(window.locator('input[name="email"]')).toBeVisible(); + await window.locator('input[name="email"]').fill("kumar") + await expect(window.locator('input[name="organization"]')).toBeVisible(); + await window.locator('input[name="organization"]').fill("v") + await expect(window.locator('input[name="selectedregion"]')).toBeVisible(); + await window.locator('input[name="selectedregion"]').fill("I") + expect(await window.locator('//*[@id="save-profile"]')).toBeVisible() + await window.locator('//*[@id="save-profile"]').click() + const firstLastNameError = await window.locator('//*[@id="__next"]/div[1]/div[2]/div/div[2]/form/div[2]/span').textContent() + expect(firstLastNameError).toBe('The input has to be between 2 and 15 characters long') + const emailError = await window.locator('//*[@id="__next"]/div[1]/div[2]/div/div[2]/form/div[3]/span').textContent() + expect(emailError).toBe('Email is not valid!') + const organizationError = await window.locator('//*[@id="__next"]/div[1]/div[2]/div/div[2]/form/div[4]/span').textContent() + expect(organizationError).toBe('The input has to be between 2 and 30 characters long') + const regionError = await window.locator('//*[@id="__next"]/div[1]/div[2]/div/div[2]/form/div[5]/span').textContent() + expect(regionError).toBe('The input has to be between 2 and 15 characters long') +} + + +// Changes the application's language. +export const changeAppLanguage = async (window, expect, fromLanguage, toLanguage) => { + expect(await window.locator('//*[@id="user-profile-image"]')).toBeVisible() + await window.locator('//*[@id="user-profile-image"]').click() + expect(await window.locator('//*[@aria-label="user-profile"]')).toBeVisible() + await window.locator('//*[@aria-label="user-profile"]').click() + await window.getByRole('button', { name: fromLanguage }).click() + await window.getByRole('option', { name: toLanguage }).click() + expect(await window.locator('//*[@id="save-profile"]')).toBeVisible() + await window.locator('//*[@id="save-profile"]').click() +} + +// sign out export const signOut = async (window, expect) => { - await expect(window.locator('//*[@id="user-profile"]')).toBeVisible() - await window.locator('//*[@id="user-profile"]').click() + await expect(window.locator('//*[@id="user-profile-image"]')).toBeVisible() + await window.locator('//*[@id="user-profile-image"]').click() await expect(window.locator('//*[@aria-label="signout"]')).toBeVisible() await window.locator('//*[@aria-label="signout"]').click() await window.waitForTimeout(1000) @@ -192,7 +322,7 @@ export const signOut = async (window, expect) => { await window.waitForTimeout(200) } -// show active user by clicking the view more but in login page +// Shows a list of active users. export const showActiveUsers = async (window, expect) => { await expect(window.locator('//*[@id="view-more"]', {timeout:5000})).toBeVisible() await window.locator('//*[@id="view-more"]', {timeout:5000}).click() diff --git a/e2e-tests/myFixtures.ts b/e2e-tests/myFixtures.ts index 7c0318327..884385686 100644 --- a/e2e-tests/myFixtures.ts +++ b/e2e-tests/myFixtures.ts @@ -1,32 +1,32 @@ -import {test as myTest} from "@playwright/test" +import { test as myTest } from "@playwright/test" type myFixture = { - userName: string - textProject: string, - obsProject: string, - audioProject: string, - syncName:string, - doorUser:string, - doorPassword:string, - flavorText:string, - flavorObs:string - textUnderscore:string, - obsUnderscore:string, - obsUrduProject:string, + userName: string + textProject: string, + obsProject: string, + audioProject: string, + syncName: string, + doorUser: string, + doorPassword: string, + flavorText: string, + flavorObs: string + textUnderscore: string, + obsUnderscore: string, + obsUrduProject: string, } const myFixtureTest = myTest.extend({ - userName : "Playwright user", - textProject: "Translation test project", - obsProject: "Obs test project", - textUnderscore: "Translation_test_project", - obsUnderscore: "Obs_test_project", - audioProject: "Audio test project", - syncName:"Sync_Collab_Test", - doorUser:"bobby", - doorPassword:"Bobby@123", - flavorText: "textTranslation", - flavorObs: "textStories", - obsUrduProject: "Obs urdu project", + userName: "Playwright user", + textProject: "Translation test project", + obsProject: "Obs test project", + textUnderscore: "Translation_test_project", + obsUnderscore: "Obs_test_project", + audioProject: "Audio test project", + syncName: "Sync_Collab_Test", + doorUser: "bobby", + doorPassword: "Bobby@123", + flavorText: "textTranslation", + flavorObs: "textStories", + obsUrduProject: "Obs urdu project", }) export const test = myFixtureTest; diff --git a/jsconfig.json b/jsconfig.json index f94e0cddc..4138fa416 100644 --- a/jsconfig.json +++ b/jsconfig.json @@ -1,5 +1,6 @@ { "compilerOptions": { + "resolveJsonModule": true, "baseUrl": ".", "paths": { "@/icons/*": [ diff --git a/renderer/src/components/Profile/UserProfile.js b/renderer/src/components/Profile/UserProfile.js index 9259adea2..45637bf9d 100644 --- a/renderer/src/components/Profile/UserProfile.js +++ b/renderer/src/components/Profile/UserProfile.js @@ -50,7 +50,7 @@ const UserProfile = () => { <>
diff --git a/renderer/src/components/Projects/ProjectList.js b/renderer/src/components/Projects/ProjectList.js index 8c58286f4..4c8f691e3 100644 --- a/renderer/src/components/Projects/ProjectList.js +++ b/renderer/src/components/Projects/ProjectList.js @@ -82,7 +82,7 @@ export default function ProjectList() {
- +
+ {projects && (stableSort( projects, getComparator(order, orderBy), @@ -167,6 +167,7 @@ const ProjectRow = ({ {({ active }) => ( -

+

{snackText}

diff --git a/renderer/src/layouts/projects/Layout.js b/renderer/src/layouts/projects/Layout.js index 9c4898ab2..7c4b023f5 100644 --- a/renderer/src/layouts/projects/Layout.js +++ b/renderer/src/layouts/projects/Layout.js @@ -103,12 +103,12 @@ export default function ProjectsLayout(props) { {showArchived ? ( <> - {t('label-active')} + {t('label-active')} ) : ( <> - {t('label-archived')} + {t('label-archived')} )} diff --git a/renderer/src/modules/projects/Profile.js b/renderer/src/modules/projects/Profile.js index 91e20f22e..6b25f923c 100644 --- a/renderer/src/modules/projects/Profile.js +++ b/renderer/src/modules/projects/Profile.js @@ -326,6 +326,7 @@ export default function UserProfile() {