diff --git a/frontend/tests/constants/DocumentConstants.ts b/frontend/tests/constants/DocumentConstants.ts new file mode 100644 index 00000000..2f46afa5 --- /dev/null +++ b/frontend/tests/constants/DocumentConstants.ts @@ -0,0 +1,17 @@ +import path from 'path'; +import { fileURLToPath } from 'url'; + +// Define the base directory for test data +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +const baseTestDataDirectory = path.join(__dirname, '../testData/'); + +// Define the constants +const constants = { + filePath: (documentName: string) => + path.join(baseTestDataDirectory, documentName), + invalidFile: path.join(baseTestDataDirectory, 'gifSample.gif'), + fileContent: 'Hello, this is the content of the file.', +}; + +export default constants; diff --git a/frontend/tests/data-factory/RegisterData.ts b/frontend/tests/data-factory/RegisterData.ts index 4f943897..5e7c5c0b 100644 --- a/frontend/tests/data-factory/RegisterData.ts +++ b/frontend/tests/data-factory/RegisterData.ts @@ -2,16 +2,14 @@ import RegisterDto from '../data-objects/RegisterDto'; class RegisterData { validRegisterData() { - const registerData = RegisterDto; - const x = Math.random() * 100; - registerData.email = 'AutomationUser' + x + '@mailinator.com'; + const registerData = new RegisterDto(); + registerData.email = 'AutomationUser' + Date.now() + '@mailinator.com'; registerData.username = 'Automation Avatar URL'; registerData.password = 'automation@123'; return registerData; } - registerDataWithoutEmail() { - const registerData = RegisterDto; + const registerData = new RegisterDto(); registerData.email = ''; registerData.username = 'Automation Avatar URL'; registerData.password = 'automation@123'; @@ -19,7 +17,7 @@ class RegisterData { } registerDataWithoutPassword() { - const registerData = RegisterDto; + const registerData = new RegisterDto(); registerData.email = 'AutomationUser12333@mailinator.com'; registerData.username = 'Automation Avatar URL'; registerData.password = ''; @@ -27,7 +25,7 @@ class RegisterData { } registerDataWithoutUserName() { - const registerData = RegisterDto; + const registerData = new RegisterDto(); registerData.email = 'AutomationUser@mailinator.com'; registerData.username = ''; registerData.password = 'automation@123'; @@ -35,7 +33,7 @@ class RegisterData { } registerDataWithInvalidEmailFormat() { - const registerData = RegisterDto; + const registerData = new RegisterDto(); registerData.email = 'Aut'; registerData.username = 'Automation Avatar URL'; registerData.password = 'automation@123'; diff --git a/frontend/tests/data-objects/RegisterDto.ts b/frontend/tests/data-objects/RegisterDto.ts index 93f50fa9..1ac70333 100644 --- a/frontend/tests/data-objects/RegisterDto.ts +++ b/frontend/tests/data-objects/RegisterDto.ts @@ -3,4 +3,4 @@ export class RegisterDto { username!: string; password!: string; } -export default new RegisterDto(); +export default RegisterDto; diff --git a/frontend/tests/pages/Community/CommonPage.ts b/frontend/tests/pages/Community/CommonPage.ts index abf78867..a2a5867a 100644 --- a/frontend/tests/pages/Community/CommonPage.ts +++ b/frontend/tests/pages/Community/CommonPage.ts @@ -28,7 +28,7 @@ class CommonPage extends BasePage { return await this.page.getByRole('heading', { name: name }).isVisible(); } async getValidationMessage() { - return await this.page.locator(`.toast-message`).textContent(); + return await this.page.locator(`.toast-message`).last().textContent(); } } export default CommonPage; diff --git a/frontend/tests/pages/Community/DocumentsPage.ts b/frontend/tests/pages/Community/DocumentsPage.ts new file mode 100644 index 00000000..f8fad94f --- /dev/null +++ b/frontend/tests/pages/Community/DocumentsPage.ts @@ -0,0 +1,99 @@ +import BasePage from '../BasePage'; + +const addNewDocumentButton = `(//span[text()='Select your language']//..//..//div)[4]//button`; +const selectedLanguage = (languageName: string) => + `//h4[text()='${languageName}']`; +const languageName = (language: string) => + `//h5[text()='${language}']//..//input`; +const documents = (documentName: string) => `//p[text()='${documentName}']`; +const meatBallsMenuButton = (documentName: string) => + `//p[text()='${documentName}']//..//..//button`; + +class DocumentsPage extends BasePage { + async isPageTitleVisible() { + return await this.page.locator(`//h2[text()='Documents']`).isVisible(); + } + async isDocumentDetailsPageVisible() { + return await this.page + .getByRole('heading', { name: 'Details' }) + .isVisible(); + } + async clickOnSelectYourLanguageDropdown() { + await this.page + .getByRole('heading', { name: 'Select your language' }) + .click(); + } + async clickOnSelectDocumentLanguageDropdown() { + await this.page + .getByRole('heading', { name: 'Select document language' }) + .click(); + } + async isSelectYourLanguagePopupVisible() { + return await this.page + .locator(`//h2[text()='Select your language']`) + .first() + .isVisible(); + } + async isAddNewDocumentPopupVisible() { + return await this.page + .getByRole('heading', { name: 'Add new document' }) + .isVisible(); + } + async selectLanguage(language: string) { + await this.page + .getByRole('textbox', { name: 'Search by language...' }) + .fill(language); + await this.page.locator(languageName(language)).first().click(); + await this.page.getByRole('button', { name: 'Confirm' }).click(); + } + async isLanguageSelected(languageName: string) { + return await this.page + .locator(selectedLanguage(languageName)) + .last() + .isVisible(); + } + async clickOnAddNewDocumentPopupCrossButton() { + await this.page.getByRole('button').first().click(); + } + async clickOnCrossButton() { + await this.page.click( + `(//span[text()='Select your language']//..//..//div)[2]//button`, + ); + } + async clickOnAddNewDocumentsButton() { + await this.page.click(addNewDocumentButton); + } + async clickOnCancelButton() { + await this.page.getByRole('button', { name: 'Cancel' }).click(); + } + async uploadTextFile(filePath: string) { + await this.page.setInputFiles('input[type="file"]', filePath); + } + async clickOnUploadButton() { + await this.page.getByRole('button', { name: 'Upload' }).click(); + } + async searchDocuments(documentName: string) { + await this.page + .getByPlaceholder(`Search by document...`) + .fill(documentName); + await this.page.waitForTimeout(1000); + } + async clickOnDocument(documentName: string) { + await this.page.locator(documents(documentName)).click(); + } + async isCreatedDocumentVisible(documentName: string) { + return await this.page.locator(documents(documentName)).isVisible(); + } + async clickOnMeatBallsMenuButton(documentName: string) { + await this.page.locator(meatBallsMenuButton(documentName)).click(); + } + async clickOnGoToDocumentsButton() { + await this.page.getByRole('button', { name: 'Go to Documents' }).click(); + } + async downloadDocument(documentName: string) { + await this.clickOnMeatBallsMenuButton(documentName); + await this.page.getByRole('button', { name: 'Download' }).click(); + } +} + +export default DocumentsPage; diff --git a/frontend/tests/pages/Community/PericopeToolPage.ts b/frontend/tests/pages/Community/PericopeToolPage.ts new file mode 100644 index 00000000..79c1b629 --- /dev/null +++ b/frontend/tests/pages/Community/PericopeToolPage.ts @@ -0,0 +1,95 @@ +import BasePage from '../BasePage'; + +const languageName = (language: string) => + `//h5[text()='${language}']//..//input`; +const randomText = "(//div[@data-test-id]/div[@data-index='0']//div/div)[1]"; +const selectedLanguageName = "//button[text()='Edit mode']/..//.//span[text()]"; +const likeDislikeButton = + "//div[@role='presentation']//div[3]//div//div//button"; +const postButton = `//div[@role='presentation']//div[3]//button`; +const documentName = "//div[@class = 'section']//h4"; + +class PericopeToolPage extends BasePage { + async isPageTitleVisible() { + return await this.page.locator(`//h2[text()='Pericope Tool']`).isVisible(); + } + async clickOnSelectYourLanguageDropdown() { + await this.page + .getByRole('heading', { name: 'Select your language' }) + .click(); + } + async clickOnSelectPericopeLanguageDropdown() { + await this.page + .getByRole('heading', { name: 'Select document language' }) + .click(); + } + async selectLanguage(language: string) { + await this.page + .getByRole('textbox', { name: 'Search by language...' }) + .fill(language); + await this.page.locator(languageName(language)).first().click(); + await this.page.getByRole('button', { name: 'Confirm' }).click(); + } + async clickOnEditMode() { + await this.page.locator("//button[text()='Edit mode']").click(); + } + async isEditModeButtonDisabled() { + return await this.page.locator("//button[text()='Edit mode']").isDisabled(); + } + async clickOnRandomTextForAddPericopeTool() { + await this.page.locator(randomText).click(); + } + async clickOnAddPericopeTool() { + await this.page.getByRole('heading', { name: 'Add Pericope' }).click(); + await this.page.waitForTimeout(1000); + } + async clickOnDeletePericopeTool() { + await this.page.getByRole('heading', { name: 'Delete Pericope' }).click(); + await this.page.waitForTimeout(1000); + } + async isPericopeToolAdded() { + return await this.page.locator(randomText + '/div').isVisible(); + } + async isPericopeToolVisible() { + return await this.page + .getByRole('heading', { name: 'Add Pericope' }) + .isVisible(); + } + async getSelectedLanguageName() { + return await this.page.locator(selectedLanguageName).textContent(); + } + async clickOnLikeButton() { + await this.page.locator(likeDislikeButton).first().click(); + await this.page.waitForTimeout(1000); + } + async getPericopeDotsColor() { + // Get background color using evaluate method + const backgroundColor = await this.page + .locator(randomText + '/div') + ?.evaluate((element) => { + return window.getComputedStyle(element).backgroundColor; + }); + return backgroundColor; + } + async clickOnDislikeButton() { + await this.page.locator(likeDislikeButton).last().click(); + await this.page.waitForTimeout(1000); + } + async clickOnPostButton() { + await this.page.locator(postButton).last().click(); + } + async getPostCount() { + return await this.page.locator(postButton).last().textContent(); + } + async getTheLikeCount() { + return await this.page.locator(likeDislikeButton).first().textContent(); + } + async getTheDislikeCount() { + return await this.page.locator(likeDislikeButton).last().textContent(); + } + async isDocumentNameIsDisplayed() { + return await this.page.locator(documentName).first().textContent(); + } +} + +export default PericopeToolPage; diff --git a/frontend/tests/pages/Community/PostPage.ts b/frontend/tests/pages/Community/PostPage.ts index c4414da7..8e9a1b50 100644 --- a/frontend/tests/pages/Community/PostPage.ts +++ b/frontend/tests/pages/Community/PostPage.ts @@ -44,7 +44,7 @@ class PostPage extends BasePage { return await this.page.locator(totalPostsCount).count(); } - async createNewPost(message: string, count: number) { + async createNewPosts(message: string, count: number) { for (let i = 0; i < count; i++) { await this.clickOnTheAddNewPostButton(); await this.clickOnTextFieldForPostMessage(); diff --git a/frontend/tests/pages/HomePage.ts b/frontend/tests/pages/HomePage.ts index 2c785cc2..b9ff14a7 100644 --- a/frontend/tests/pages/HomePage.ts +++ b/frontend/tests/pages/HomePage.ts @@ -3,6 +3,7 @@ import BasePage from './BasePage'; const homePageTitle = '//div[@class="section"]/ion-item-group//ion-label[text() = "Media"]'; const homePageText = `//ion-label[text()]`; +const headerText = '#crowd-rock-app #app-name-text'; const expandIcon = '#app-menu-button'; const languageText = '//ion-label[text() = "Language"]'; @@ -11,7 +12,9 @@ class HomePage extends BasePage { await this.page.locator(homePageTitle).waitFor(); return await this.page.locator(homePageTitle).isVisible(); } - + async clickOnCrowdRocks() { + await this.page.locator(headerText).first().click(); + } async getHomePageTitle() { return await this.page.locator(homePageText).first().textContent(); } @@ -33,6 +36,18 @@ class HomePage extends BasePage { .filter({ hasText: 'Forums' }) .click(); } + async clickOnTheDocumentsSection() { + await this.page + .locator('ion-card-header') + .filter({ hasText: 'Documents' }) + .click(); + } + async clickOnThePericopeToolSection() { + await this.page + .locator('ion-card-header') + .filter({ hasText: 'Pericope Tool' }) + .click(); + } } export default HomePage; diff --git a/frontend/tests/pages/MenuPage.ts b/frontend/tests/pages/MenuPage.ts index 9519a231..965fd535 100644 --- a/frontend/tests/pages/MenuPage.ts +++ b/frontend/tests/pages/MenuPage.ts @@ -1,6 +1,7 @@ import BasePage from './BasePage'; const headerText = '#crowd-rock-app #app-name-text'; + const leftMenuFeatureButton = (featureName: string) => `//h4[text()="${featureName}"]`; @@ -18,10 +19,6 @@ class MenuPage extends BasePage { await this.page.locator(leftMenuFeatureButton(featureName)).first().click(); await this.page.waitForTimeout(1000); } - - async clickOnCrowdRocks() { - await this.page.locator(headerText).first().click(); - } } export default MenuPage; diff --git a/frontend/tests/test/CommunityTests/CommunityEndToEndFlowTest.Spec.ts b/frontend/tests/test/CommunityTests/CommunityEndToEndFlowTest.Spec.ts index 610499eb..1900d0e1 100644 --- a/frontend/tests/test/CommunityTests/CommunityEndToEndFlowTest.Spec.ts +++ b/frontend/tests/test/CommunityTests/CommunityEndToEndFlowTest.Spec.ts @@ -93,7 +93,7 @@ test('1: End to end linear flow for Community forums', async ({ page }) => { //Create a new two posts await threadsPage.clickOnThreadName(threadNameOne); - await postPage.createNewPost(postTextMessage, 2); + await postPage.createNewPosts(postTextMessage, 2); //Get posts count from the post page and verify that on the threads page const expectedPostsCount = await postPage.getPostsCount(); diff --git a/frontend/tests/test/DocumentsTests.Spec.ts b/frontend/tests/test/DocumentsTests.Spec.ts new file mode 100644 index 00000000..75e706d4 --- /dev/null +++ b/frontend/tests/test/DocumentsTests.Spec.ts @@ -0,0 +1,355 @@ +import { Page, chromium, expect, test } from '@playwright/test'; +import PageUrls from '../constants/PageUrls'; +import RegistrationPage from '../pages/RegistrationPage'; +import RegisterData from '../data-factory/RegisterData'; +import DocumentsPage from '../pages/Community/DocumentsPage'; +import HomePage from '../pages/HomePage'; +import LoginPage from '../pages/LoginPage'; +import { language, settings } from '../enums/Enums'; +import SettingsPage from '../pages/SettingsPage'; +import CommonPage from '../pages/Community/CommonPage'; +import constants from '../constants/DocumentConstants'; +import { writeFileSync } from 'fs'; + +const registerData = RegisterData.validRegisterData(); +const documentName = await generateUniqueFileName('txt'); + +test.beforeAll(async () => { + const browser = await chromium.launch({ headless: true }); + const context = await browser.newContext(); + const page = await context.newPage(); + const registerPage = new RegistrationPage(page); + + writeFileSync(constants.filePath(documentName), constants.fileContent); + //Navigate to the URL + await page.goto(PageUrls.RegisterPage); + + //Verify the title of the page + expect(await registerPage.isRegisterPageTitleVisible()).toBeTruthy(); + + //Fill and submit the register form + await registerPage.fillRegistrationForm(registerData); + await registerPage.clickOnRegisterButton(); + await page.waitForTimeout(3000); +}); + +async function generateUniqueFileName(extension: string): Promise { + const timestamp = new Date().toISOString().replace(/[-:.]/g, ''); + const randomString = Math.random().toString(36).substring(7); + return `${timestamp}_${randomString}.${extension}`; +} + +async function turnOnBetaTools(page: Page) { + const settingsPage = new SettingsPage(page); + const homePage = new HomePage(page); + + //Navigate to the URL + await page.goto(PageUrls.SettingsPage); + + //Click on beta tools toggle button + await settingsPage.clickOnToggleButton(settings.BetaTools, true); + await homePage.clickOnCrowdRocks(); +} + +test('1: Verify that user can upload document successfully', async ({ + page, +}) => { + const loginPage = new LoginPage(page); + const documentsPage = new DocumentsPage(page); + const homePage = new HomePage(page); + const commonPage = new CommonPage(page); + + //Login with valid credentials and turn on the beta tools + await page.goto(PageUrls.LoginPage); + await loginPage.loginToApp(registerData); + await turnOnBetaTools(page); + + //Navigate to documents page and select language + await homePage.clickOnTheDocumentsSection(); + expect(await documentsPage.isPageTitleVisible()).toBeTruthy(); + await documentsPage.clickOnSelectYourLanguageDropdown(); + await documentsPage.selectLanguage(language.English); + + await documentsPage.clickOnAddNewDocumentsButton(); + expect(await documentsPage.isAddNewDocumentPopupVisible()).toBeTruthy(); + + //Verify that language is selected + expect(await documentsPage.isLanguageSelected(language.English)).toBeTruthy(); + const [uploadFile] = await Promise.all([ + page.waitForEvent('filechooser'), + await documentsPage.clickOnUploadButton(), + ]); + uploadFile.setFiles(constants.filePath(documentName)); + expect(await commonPage.getValidationMessage()).toEqual( + 'Success at uploading new document!', + ); + await documentsPage.clickOnGoToDocumentsButton(); + await documentsPage.searchDocuments(documentName.toLocaleLowerCase()); + expect( + await documentsPage.isCreatedDocumentVisible(documentName), + ).toBeTruthy(); +}); + +test('2: Verify user can download the document successfully', async ({ + page, +}) => { + const loginPage = new LoginPage(page); + const documentsPage = new DocumentsPage(page); + const homePage = new HomePage(page); + + //Login with valid credentials and turn on the beta tools + await page.goto(PageUrls.LoginPage); + await loginPage.loginToApp(registerData); + await turnOnBetaTools(page); + + //Navigate to documents page and select language + await homePage.clickOnTheDocumentsSection(); + await documentsPage.clickOnSelectYourLanguageDropdown(); + await documentsPage.selectLanguage(language.English); + await documentsPage.searchDocuments(documentName.toLocaleLowerCase()); + + const [download] = await Promise.all([ + page.waitForEvent('download'), + documentsPage.downloadDocument(documentName), + ]); + expect(download).not.toBeNull(); + expect(download.url()).toContain(documentName); +}); + +test('3: Verify user can redirected on document details page successfully', async ({ + page, +}) => { + const loginPage = new LoginPage(page); + const documentsPage = new DocumentsPage(page); + const homePage = new HomePage(page); + + //Login with valid credentials and turn on the beta tools + await page.goto(PageUrls.LoginPage); + await loginPage.loginToApp(registerData); + await turnOnBetaTools(page); + + //Navigate to documents page and select language + await homePage.clickOnTheDocumentsSection(); + await documentsPage.clickOnSelectYourLanguageDropdown(); + await documentsPage.selectLanguage(language.English); + + //search the create document and click on document name + await documentsPage.searchDocuments(documentName.toLocaleLowerCase()); + await documentsPage.clickOnDocument(documentName); + + //verify that document details page is open + expect(await documentsPage.isDocumentDetailsPageVisible()).toBeTruthy(); +}); + +test('4: Verify that user is not allowed to upload documents with the name which already exists', async ({ + page, +}) => { + const loginPage = new LoginPage(page); + const documentsPage = new DocumentsPage(page); + const homePage = new HomePage(page); + const commonPage = new CommonPage(page); + + //Login with valid credentials and turn on the beta tools + await page.goto(PageUrls.LoginPage); + await loginPage.loginToApp(registerData); + await turnOnBetaTools(page); + + //Navigate to documents page and select language + await homePage.clickOnTheDocumentsSection(); + expect(await documentsPage.isPageTitleVisible()).toBeTruthy(); + await documentsPage.clickOnSelectYourLanguageDropdown(); + await documentsPage.selectLanguage(language.English); + + await documentsPage.clickOnAddNewDocumentsButton(); + expect(await documentsPage.isAddNewDocumentPopupVisible()).toBeTruthy(); + + //Verify that language is selected + expect(await documentsPage.isLanguageSelected(language.English)).toBeTruthy(); + await documentsPage.uploadTextFile(constants.filePath(documentName)); + expect(await commonPage.getValidationMessage()).toEqual( + 'File with this name already exists', + ); +}); + +test.skip('5: Verify that validation message is appeared when user uploads the invalid file', async ({ + page, +}) => { + const loginPage = new LoginPage(page); + const documentsPage = new DocumentsPage(page); + const homePage = new HomePage(page); + const commonPage = new CommonPage(page); + + //Login with valid credentials and turn on the beta tools + await page.goto(PageUrls.LoginPage); + await loginPage.loginToApp(registerData); + await turnOnBetaTools(page); + + //Navigate to documents page and select language + await homePage.clickOnTheDocumentsSection(); + expect(await documentsPage.isPageTitleVisible()).toBeTruthy(); + await documentsPage.clickOnSelectYourLanguageDropdown(); + await documentsPage.selectLanguage(language.English); + + await documentsPage.clickOnAddNewDocumentsButton(); + expect(await documentsPage.isAddNewDocumentPopupVisible()).toBeTruthy(); + + //Verify that language is selected + expect(await documentsPage.isLanguageSelected(language.English)).toBeTruthy(); + const [uploadFile] = await Promise.all([ + page.waitForEvent('filechooser'), + await documentsPage.clickOnUploadButton(), + ]); + uploadFile.setFiles(constants.invalidFile); + expect(await commonPage.getValidationMessage()).toEqual( + 'Failed at uploading new Document! [UnknownError]', + ); +}); + +test('6: Verify that validation message is appeared when user uploads the file without selecting the language', async ({ + page, +}) => { + const loginPage = new LoginPage(page); + const documentsPage = new DocumentsPage(page); + const commonPage = new CommonPage(page); + const homePage = new HomePage(page); + + //Login with valid credentials and turn on the beta tools + await page.goto(PageUrls.LoginPage); + await loginPage.loginToApp(registerData); + await turnOnBetaTools(page); + + //Navigate to documents page + await homePage.clickOnTheDocumentsSection(); + + //Upload text file without selecting the language + await documentsPage.clickOnAddNewDocumentsButton(); + expect(await documentsPage.isAddNewDocumentPopupVisible()).toBeTruthy(); + await documentsPage.uploadTextFile(constants.filePath(documentName)); + expect(await commonPage.getValidationMessage()).toEqual( + 'Please select document language first.', + ); +}); + +test('7: Verify that user can select & cancel language successfully', async ({ + page, +}) => { + const loginPage = new LoginPage(page); + const documentsPage = new DocumentsPage(page); + const homePage = new HomePage(page); + + //Login with valid credentials and turn on the beta tools + await page.goto(PageUrls.LoginPage); + await loginPage.loginToApp(registerData); + await turnOnBetaTools(page); + + //Navigate to documents page and select language + await homePage.clickOnTheDocumentsSection(); + expect(await documentsPage.isPageTitleVisible()).toBeTruthy(); + await documentsPage.clickOnSelectYourLanguageDropdown(); + await documentsPage.selectLanguage(language.English); + + //Verify that language is selected + expect(await documentsPage.isLanguageSelected(language.English)).toBeTruthy(); + + //Deselect the language + await documentsPage.clickOnCrossButton(); + expect(await documentsPage.isLanguageSelected(language.English)).toBeFalsy(); +}); + +test('8: Verify that select your language popup is closed when user clicks on the cancel button', async ({ + page, +}) => { + const loginPage = new LoginPage(page); + const documentsPage = new DocumentsPage(page); + const homePage = new HomePage(page); + + //Login with valid credentials and turn on the beta tools + await page.goto(PageUrls.LoginPage); + await loginPage.loginToApp(registerData); + await turnOnBetaTools(page); + + //Navigate to documents page and click on the select your language dropdown + await homePage.clickOnTheDocumentsSection(); + expect(await documentsPage.isPageTitleVisible()).toBeTruthy(); + await documentsPage.clickOnSelectYourLanguageDropdown(); + expect(await documentsPage.isSelectYourLanguagePopupVisible()).toBeTruthy(); + + // Click on the cancel button + await documentsPage.clickOnCancelButton(); + + // Verify that select your language popup is closed + expect(await documentsPage.isSelectYourLanguagePopupVisible()).toBeFalsy(); +}); + +test('9: Verify that language is selected on the Add new document popup is the same as selected on the Documents page', async ({ + page, +}) => { + const loginPage = new LoginPage(page); + const documentsPage = new DocumentsPage(page); + const homePage = new HomePage(page); + + //Login with valid credentials and turn on the beta tools + await page.goto(PageUrls.LoginPage); + await loginPage.loginToApp(registerData); + await turnOnBetaTools(page); + + //Navigate to documents page and click on the select your language dropdown + await homePage.clickOnTheDocumentsSection(); + expect(await documentsPage.isPageTitleVisible()).toBeTruthy(); + await documentsPage.clickOnSelectYourLanguageDropdown(); + expect(await documentsPage.isSelectYourLanguagePopupVisible()).toBeTruthy(); + + // Select your language + await documentsPage.selectLanguage(language.English); + await documentsPage.clickOnAddNewDocumentsButton(); + + // Verify that selected language is displayed + expect(await documentsPage.isLanguageSelected(language.English)); +}); + +test('10: Verify that user is able to select & cancel the language from the dropdown list successfully', async ({ + page, +}) => { + const loginPage = new LoginPage(page); + const documentsPage = new DocumentsPage(page); + const homePage = new HomePage(page); + + //Login with valid credentials and turn on the beta tools + await page.goto(PageUrls.LoginPage); + await loginPage.loginToApp(registerData); + await turnOnBetaTools(page); + + //Navigate to documents page and select language + await homePage.clickOnTheDocumentsSection(); + expect(await documentsPage.isPageTitleVisible()).toBeTruthy(); + await documentsPage.clickOnAddNewDocumentsButton(); + await documentsPage.clickOnSelectDocumentLanguageDropdown(); + await documentsPage.selectLanguage(language.English); + expect(await documentsPage.isLanguageSelected(language.English)).toBeTruthy(); + + //Deselect the language + await documentsPage.clickOnAddNewDocumentPopupCrossButton(); + expect(await documentsPage.isLanguageSelected(language.English)).toBeFalsy(); +}); + +test('11: Verify that add new document popup is closed when user click on the cancel button', async ({ + page, +}) => { + const loginPage = new LoginPage(page); + const documentsPage = new DocumentsPage(page); + const homePage = new HomePage(page); + + //Login with valid credentials and turn on the beta tools + await page.goto(PageUrls.LoginPage); + await loginPage.loginToApp(registerData); + await turnOnBetaTools(page); + + //Navigate to documents page and select language + await homePage.clickOnTheDocumentsSection(); + await documentsPage.clickOnAddNewDocumentsButton(); + expect(await documentsPage.isAddNewDocumentPopupVisible()).toBeTruthy(); + await documentsPage.clickOnCancelButton(); + + //Verify that Add new popup is closed + expect(await documentsPage.isAddNewDocumentPopupVisible()).toBeFalsy(); +}); diff --git a/frontend/tests/test/PericopeToolTests.Spec.ts b/frontend/tests/test/PericopeToolTests.Spec.ts new file mode 100644 index 00000000..99151b48 --- /dev/null +++ b/frontend/tests/test/PericopeToolTests.Spec.ts @@ -0,0 +1,347 @@ +import { Page, chromium, expect, test } from '@playwright/test'; +import PageUrls from '../constants/PageUrls'; +import RegistrationPage from '../pages/RegistrationPage'; +import RegisterData from '../data-factory/RegisterData'; +import DocumentsPage from '../pages/Community/DocumentsPage'; +import HomePage from '../pages/HomePage'; +import LoginPage from '../pages/LoginPage'; +import { language, leftMenu, settings } from '../enums/Enums'; +import CommonPage from '../pages/Community/CommonPage'; +import constants from '../constants/DocumentConstants'; +import { writeFileSync } from 'fs'; +import PericopeToolPage from '../pages/Community/PericopeToolPage'; +import SettingsPage from '../pages/SettingsPage'; +import PostPage from '../pages/Community/PostPage'; +import MenuPage from '../pages/MenuPage'; +test.use({ storageState: { cookies: [], origins: [] } }); + +const registerData = RegisterData.validRegisterData(); +const documentName = await generateUniqueFileName('txt'); + +test.beforeAll(async () => { + const browser = await chromium.launch({ headless: true }); + const context = await browser.newContext(); + const page = await context.newPage(); + const registerPage = new RegistrationPage(page); + const documentsPage = new DocumentsPage(page); + const homePage = new HomePage(page); + const commonPage = new CommonPage(page); + + writeFileSync(constants.filePath(documentName), constants.fileContent); + + //Navigate to the URL + await page.goto(PageUrls.RegisterPage); + + //Verify the title of the page + expect(await registerPage.isRegisterPageTitleVisible()).toBeTruthy(); + + //Fill and submit the register form + await registerPage.fillRegistrationForm(registerData); + await registerPage.clickOnRegisterButton(); + await page.waitForTimeout(3000); + await turnOnBetaTools(page); + + //Navigate to documents page and select language + await homePage.clickOnTheDocumentsSection(); + expect(await documentsPage.isPageTitleVisible()).toBeTruthy(); + await documentsPage.clickOnSelectYourLanguageDropdown(); + await documentsPage.selectLanguage(language.English); + await documentsPage.clickOnAddNewDocumentsButton(); + expect(await documentsPage.isAddNewDocumentPopupVisible()).toBeTruthy(); + const [uploadFile] = await Promise.all([ + page.waitForEvent('filechooser'), + await documentsPage.clickOnUploadButton(), + ]); + uploadFile.setFiles(constants.filePath(documentName)); + expect(await commonPage.getValidationMessage()).toEqual( + 'Success at uploading new document!', + ); +}); + +async function generateUniqueFileName(extension: string): Promise { + const timestamp = new Date().toISOString().replace(/[-:.]/g, ''); + const randomString = Math.random().toString(36).substring(7); + return `${timestamp}_${randomString}.${extension}`; +} + +async function turnOnBetaTools(page: Page) { + const settingsPage = new SettingsPage(page); + const homePage = new HomePage(page); + + //Navigate to the URL + await page.goto(PageUrls.SettingsPage); + + //Click on beta tools toggle button + await settingsPage.clickOnToggleButton(settings.BetaTools, true); + await homePage.clickOnCrowdRocks(); +} + +async function clickOnPericopeToolAndSearchDocument(page: Page) { + const loginPage = new LoginPage(page); + const pericopeToolPage = new PericopeToolPage(page); + const homePage = new HomePage(page); + + //Login with valid credentials and turn on the beta tools + await page.goto(PageUrls.LoginPage); + await loginPage.loginToApp(registerData); + await turnOnBetaTools(page); + + //Navigate to documents page and select language + await homePage.clickOnThePericopeToolSection(); + expect(await pericopeToolPage.isPageTitleVisible()).toBeTruthy(); + await pericopeToolPage.clickOnSelectYourLanguageDropdown(); + await pericopeToolPage.selectLanguage(language.English); +} + +async function loginWithNewUser(page: Page) { + const registerPage = new RegistrationPage(page); + const registerData = RegisterData.validRegisterData(); + //Navigate to the URL + await page.goto(PageUrls.RegisterPage); + + //Verify the title of the page + expect(await registerPage.isRegisterPageTitleVisible()).toBeTruthy(); + + //Fill and submit the register form + await registerPage.fillRegistrationForm(registerData); + await registerPage.clickOnRegisterButton(); + await page.waitForTimeout(3000); +} +test('1: Verify that added document is displayed when user search the document in pericope tool page', async ({ + page, +}) => { + const documentsPage = new DocumentsPage(page); + await clickOnPericopeToolAndSearchDocument(page); + + //Search the document name and click on that document + await documentsPage.searchDocuments(documentName.toLocaleLowerCase()); + expect(documentsPage.isCreatedDocumentVisible(documentName)).toBeTruthy(); +}); + +test('2: Verify that user can add a pericopes in document successfully', async ({ + page, +}) => { + const pericopeToolPage = new PericopeToolPage(page); + const documentsPage = new DocumentsPage(page); + await clickOnPericopeToolAndSearchDocument(page); + + //Search the document name and click on that document + await documentsPage.searchDocuments(documentName.toLocaleLowerCase()); + await documentsPage.clickOnDocument(documentName); + + //verify that document name is displayed in details page + expect(await pericopeToolPage.isDocumentNameIsDisplayed()).toBeTruthy(); + + //Click on edit mode in pericope tool page + await pericopeToolPage.clickOnEditMode(); + await pericopeToolPage.clickOnRandomTextForAddPericopeTool(); + + await pericopeToolPage.clickOnAddPericopeTool(); + expect(await pericopeToolPage.getPericopeDotsColor()).toEqual( + 'rgb(71, 111, 255)', + ); +}); + +test('3: Verify that user is able to add/remove like and dislike on the pericode successfully', async ({ + page, +}) => { + const pericopeToolPage = new PericopeToolPage(page); + const documentsPage = new DocumentsPage(page); + await clickOnPericopeToolAndSearchDocument(page); + + //Search the document name and click on that document + await documentsPage.searchDocuments(documentName.toLocaleLowerCase()); + await documentsPage.clickOnDocument(documentName); + + //Click on edit mode in pericope tool page + await pericopeToolPage.clickOnRandomTextForAddPericopeTool(); + + //add like + await pericopeToolPage.clickOnLikeButton(); + expect(await pericopeToolPage.getPericopeDotsColor()).toEqual( + 'rgb(20, 201, 114)', + ); + expect(await pericopeToolPage.getTheLikeCount()).toEqual('1'); + expect(await pericopeToolPage.getTheDislikeCount()).toEqual('0'); + + //Remove like + await pericopeToolPage.clickOnLikeButton(); + expect(await pericopeToolPage.getPericopeDotsColor()).toEqual( + 'rgb(71, 111, 255)', + ); + expect(await pericopeToolPage.getTheLikeCount()).toEqual('0'); + expect(await pericopeToolPage.getTheDislikeCount()).toEqual('0'); + + //Add dislike + await pericopeToolPage.clickOnDislikeButton(); + expect(await pericopeToolPage.getPericopeDotsColor()).toEqual( + 'rgb(255, 71, 71)', + ); + expect(await pericopeToolPage.getTheLikeCount()).toEqual('0'); + expect(await pericopeToolPage.getTheDislikeCount()).toEqual('1'); + + //Remove dislike + await pericopeToolPage.clickOnDislikeButton(); + expect(await pericopeToolPage.getPericopeDotsColor()).toEqual( + 'rgb(71, 111, 255)', + ); + expect(await pericopeToolPage.getTheLikeCount()).toEqual('0'); + expect(await pericopeToolPage.getTheDislikeCount()).toEqual('0'); +}); + +test('4: Verify that user is able to add posts in the added pericode successfully', async ({ + page, +}) => { + const pericopeToolPage = new PericopeToolPage(page); + const documentsPage = new DocumentsPage(page); + + const postPage = new PostPage(page); + const postTextMessage = 'Automation Post Message' + Math.random(); + + await clickOnPericopeToolAndSearchDocument(page); + + //Search the document name and click on that document + await documentsPage.searchDocuments(documentName.toLocaleLowerCase()); + await documentsPage.clickOnDocument(documentName); + + //Click on edit mode in pericope tool page + await pericopeToolPage.clickOnRandomTextForAddPericopeTool(); + await pericopeToolPage.clickOnPostButton(); + await postPage.createNewPosts(postTextMessage, 2); + await postPage.clickOnBackArrowButton(); + await pericopeToolPage.clickOnRandomTextForAddPericopeTool(); + expect(await pericopeToolPage.getPostCount()).toEqual('2'); +}); + +test('5: Verify that user can delete a pericopes in document successfully', async ({ + page, +}) => { + const pericopeToolPage = new PericopeToolPage(page); + const documentsPage = new DocumentsPage(page); + + await clickOnPericopeToolAndSearchDocument(page); + + //Search the document name and click on that document + await documentsPage.searchDocuments(documentName.toLocaleLowerCase()); + await documentsPage.clickOnDocument(documentName); + + //Click on edit mode in pericope tool page + await pericopeToolPage.clickOnEditMode(); + + //Delete the added pericope + await pericopeToolPage.clickOnRandomTextForAddPericopeTool(); + await pericopeToolPage.clickOnDeletePericopeTool(); + + //Verify that added pericode is removed + expect(await pericopeToolPage.isPericopeToolAdded()).toBeFalsy(); +}); + +test('6: Verify that user is not able to add the pericope tool when edit mode is off', async ({ + page, +}) => { + const pericopeToolPage = new PericopeToolPage(page); + const documentsPage = new DocumentsPage(page); + + await clickOnPericopeToolAndSearchDocument(page); + + //Search the document name and click on that document + await documentsPage.searchDocuments(documentName.toLocaleLowerCase()); + await documentsPage.clickOnDocument(documentName); + + await pericopeToolPage.clickOnRandomTextForAddPericopeTool(); + expect(await pericopeToolPage.isPericopeToolVisible()).toBeFalsy(); +}); + +test('7: Verify that selected language name is displayed in pericope tool detail page', async ({ + page, +}) => { + const pericopeToolPage = new PericopeToolPage(page); + const documentsPage = new DocumentsPage(page); + + await clickOnPericopeToolAndSearchDocument(page); + + //Search the document name and click on that document + await documentsPage.searchDocuments(documentName.toLocaleLowerCase()); + await documentsPage.clickOnDocument(documentName); + + expect(await pericopeToolPage.getSelectedLanguageName()).toMatch( + language.English, + ); +}); + +test('8: Verify that user is not able to add pericope in the document which is created by different user', async ({ + page, +}) => { + const pericopeToolPage = new PericopeToolPage(page); + const documentsPage = new DocumentsPage(page); + const homePage = new HomePage(page); + const leftMenuPage = new MenuPage(page); + await loginWithNewUser(page); + await turnOnBetaTools(page); + + //Navigate to documents page and select language + await homePage.clickOnThePericopeToolSection(); + expect(await pericopeToolPage.isPageTitleVisible()).toBeTruthy(); + await pericopeToolPage.clickOnSelectYourLanguageDropdown(); + await pericopeToolPage.selectLanguage(language.English); + + //Search the document name and click on that document + await documentsPage.searchDocuments(documentName.toLocaleLowerCase()); + await documentsPage.clickOnDocument(documentName); + + expect(await pericopeToolPage.isEditModeButtonDisabled()).toBeTruthy(); + //logout from the app + await homePage.clickOnExpandMenu(); + await leftMenuPage.clickOnLeftMenufeatureButton(leftMenu.Logout); +}); + +test('9: Verify that user is able to add like/dislike to the pericode in the document which is created by different user', async ({ + page, +}) => { + const loginPage = new LoginPage(page); + const pericopeToolPage = new PericopeToolPage(page); + const documentsPage = new DocumentsPage(page); + const homePage = new HomePage(page); + + //Login with valid credentials and turn on the beta tools + await page.goto(PageUrls.LoginPage); + await loginPage.loginToApp(registerData); + await turnOnBetaTools(page); + + //Navigate to documents page and select language + await homePage.clickOnThePericopeToolSection(); + expect(await pericopeToolPage.isPageTitleVisible()).toBeTruthy(); + await pericopeToolPage.clickOnSelectYourLanguageDropdown(); + await pericopeToolPage.selectLanguage(language.English); + + //Search the document name and click on that document + await documentsPage.searchDocuments(documentName.toLocaleLowerCase()); + await documentsPage.clickOnDocument(documentName); + + //Click on edit mode in pericope tool page + await pericopeToolPage.clickOnEditMode(); + await pericopeToolPage.clickOnRandomTextForAddPericopeTool(); + await pericopeToolPage.clickOnAddPericopeTool(); + await pericopeToolPage.clickOnEditMode(); + + //add like + await pericopeToolPage.clickOnRandomTextForAddPericopeTool(); + await pericopeToolPage.clickOnLikeButton(); + expect(await pericopeToolPage.getTheLikeCount()).toEqual('1'); + + await loginWithNewUser(page); + + //Navigate to documents page and select language + await homePage.clickOnThePericopeToolSection(); + + //Search the document name and click on that document + await documentsPage.searchDocuments(documentName.toLocaleLowerCase()); + await documentsPage.clickOnDocument(documentName); + + await pericopeToolPage.clickOnRandomTextForAddPericopeTool(); + expect(await pericopeToolPage.getTheLikeCount()).toEqual('1'); + + //add like + await pericopeToolPage.clickOnLikeButton(); + expect(await pericopeToolPage.getTheLikeCount()).toEqual('2'); +}); diff --git a/frontend/tests/test/SettingsTests.Spec.ts b/frontend/tests/test/SettingsTests.Spec.ts index cd8fe2c1..a32901ad 100644 --- a/frontend/tests/test/SettingsTests.Spec.ts +++ b/frontend/tests/test/SettingsTests.Spec.ts @@ -33,7 +33,6 @@ test('Verify that all the Beta tools are displayed when user enable beta tools t page, }) => { const homePage = new HomePage(page); - const leftMenuPage = new MenuPage(page); const settingsPage = new SettingsPage(page); const getSettingsList = SettingsData.allSettingsList(); @@ -48,7 +47,7 @@ test('Verify that all the Beta tools are displayed when user enable beta tools t await settingsPage.clickOnToggleButton(settings.BetaTools, true); //Go to the home page and verify the language text is displayed - await leftMenuPage.clickOnCrowdRocks(); + await homePage.clickOnCrowdRocks(); expect(await homePage.isLanguageTextVisible()).toBeTruthy(); //Expand the menu and click on settings @@ -58,7 +57,7 @@ test('Verify that all the Beta tools are displayed when user enable beta tools t await settingsPage.clickOnToggleButton(settings.BetaTools, false); //Go to the home page and verify the language text is hide - await leftMenuPage.clickOnCrowdRocks(); + await homePage.clickOnCrowdRocks(); expect(await homePage.isLanguageTextVisible(false)); }); diff --git a/frontend/tests/testData/gifSample.gif b/frontend/tests/testData/gifSample.gif new file mode 100644 index 00000000..d41b6a15 Binary files /dev/null and b/frontend/tests/testData/gifSample.gif differ