Req - 03 validation package (#6127)

Signed-off-by: Jasmin <jasmin@hardcoreeng.com>
This commit is contained in:
JasminMus 2024-07-31 18:59:12 +02:00 committed by GitHub
parent c2ef139e29
commit 868556471d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 449 additions and 2 deletions

View File

@ -12,7 +12,7 @@ import { allure } from 'allure-playwright'
import { DocumentsPage } from '../model/documents/documents-page'
import { DocumentDetails, DocumentRights, DocumentStatus, NewDocument } from '../model/types'
import { DocumentContentPage } from '../model/documents/document-content-page'
import { prepareDocumentStep } from '../documents/common-documents-steps'
import { prepareDocumentStep } from './common-documents-steps'
import { DocumentHistoryPage } from '../model/documents/document-history-page'

View File

@ -0,0 +1,169 @@
import { test, expect } from '@playwright/test'
import {
attachScreenshot,
DocumentURI,
generateId,
getSecondPage,
HomepageURI,
PlatformSetting,
PlatformURI
} from '../utils'
import { allure } from 'allure-playwright'
import { DocumentsPage } from '../model/documents/documents-page'
import { Content, DocumentDetails, DocumentRights, DocumentStatus, NewDocument } from '../model/types'
import { DocumentContentPage } from '../model/documents/document-content-page'
import { prepareDocumentStep } from './common-documents-steps'
import { faker } from '@faker-js/faker'
test.use({
storageState: PlatformSetting
})
test.describe('ISO 13485, 4.2.4 Control of documents', () => {
test.beforeEach(async ({ page }) => {
await (await page.goto(`${PlatformURI}/${HomepageURI}`))?.finished()
})
test('TESTS-399. Tool does not influence content: Entered text in a document does not change over time', async ({
page,
browser
}) => {
await allure.description(
'Requirement\nUsers need to make a resolve all comments and done documents for the Effective status'
)
await allure.tms('TESTS-399', 'https://tracex.hc.engineering/workbench/platform/tracker/TESTS-399')
const userSecondPage = await getSecondPage(browser)
const completeDocument: NewDocument = {
template: 'HR (HR)',
title: `Complete document-${generateId()}`,
description: `Complete document description-${generateId()}`
}
const reviewer = 'Dirak Kainin'
const documentDetails: DocumentDetails = {
type: 'HR',
category: 'Human Resources',
version: 'v0.1',
status: DocumentStatus.DRAFT,
owner: 'Appleseed John',
author: 'Appleseed John'
}
const newContent: Content = {
sectionTitle: `Overview-${generateId()}`,
content: faker.lorem.paragraphs(10)
}
await prepareDocumentStep(page, completeDocument)
const documentContentPage = new DocumentContentPage(page)
await documentContentPage.updateSectionTitle('1', newContent.sectionTitle)
await documentContentPage.addContentToTheSection(newContent)
await test.step('2. Send for Approval', async () => {
await documentContentPage.buttonSendForApproval.click()
await documentContentPage.fillSelectApproversForm([reviewer])
await documentContentPage.checkDocumentStatus(DocumentStatus.IN_APPROVAL)
await documentContentPage.checkDocument({
...documentDetails,
status: DocumentStatus.IN_APPROVAL,
version: 'v0.1'
})
await documentContentPage.checkCurrentRights(DocumentRights.VIEWING)
})
await test.step('3. Approve document', async () => {
const documentsPageSecond = new DocumentsPage(userSecondPage)
await (await userSecondPage.goto(`${PlatformURI}/${DocumentURI}`))?.finished()
await documentsPageSecond.openDocument(completeDocument.title)
const documentContentPageSecond = new DocumentContentPage(userSecondPage)
await documentContentPageSecond.confirmApproval()
await documentContentPageSecond.checkDocumentStatus(DocumentStatus.EFFECTIVE)
await documentContentPageSecond.checkDocument({
...documentDetails,
status: DocumentStatus.EFFECTIVE,
version: 'v0.1'
})
await documentContentPageSecond.checkCurrentRights(DocumentRights.VIEWING)
await attachScreenshot('TESTS-399_approve_document.png', page)
})
await test.step('4. Check the content of the draft matches the approved version', async () => {
const actualText = await page.locator('.tiptap').innerText()
const expectedText = newContent.content.trim().replace(/\s+/g, ' ')
const cleanedActualText = actualText.trim().replace(/\s+/g, ' ')
expect(cleanedActualText).toContain(expectedText)
await attachScreenshot('TESTS-399-check_content.png', page)
})
})
test.skip('TESTS-271. Generate a PDF from an Effective doc', async ({ page, browser }) => {
await allure.description(
'Requirement\nUsers need to make a resolve all comments and done documents for the Effective status'
)
await allure.tms('TESTS-271', 'https://tracex.hc.engineering/workbench/platform/tracker/TESTS-271')
const userSecondPage = await getSecondPage(browser)
const completeDocument: NewDocument = {
template: 'HR (HR)',
title: `Complete document-${generateId()}`,
description: `Complete document description-${generateId()}`
}
const reviewer = 'Dirak Kainin'
const documentDetails: DocumentDetails = {
type: 'HR',
category: 'Human Resources',
version: 'v0.1',
status: DocumentStatus.DRAFT,
owner: 'Appleseed John',
author: 'Appleseed John'
}
const newContent: Content = {
sectionTitle: `Overview-${generateId()}`,
content: faker.lorem.paragraphs(10)
}
await prepareDocumentStep(page, completeDocument)
const documentContentPage = new DocumentContentPage(page)
await documentContentPage.updateSectionTitle('1', newContent.sectionTitle)
await documentContentPage.addContentToTheSection(newContent)
await test.step('2. Send for Approval', async () => {
await documentContentPage.buttonSendForApproval.click()
await documentContentPage.fillSelectApproversForm([reviewer])
await documentContentPage.checkDocumentStatus(DocumentStatus.IN_APPROVAL)
await documentContentPage.checkDocument({
...documentDetails,
status: DocumentStatus.IN_APPROVAL,
version: 'v0.1'
})
await documentContentPage.checkCurrentRights(DocumentRights.VIEWING)
})
await test.step('3. Approve document', async () => {
const documentsPageSecond = new DocumentsPage(userSecondPage)
await (await userSecondPage.goto(`${PlatformURI}/${DocumentURI}`))?.finished()
await documentsPageSecond.openDocument(completeDocument.title)
const documentContentPageSecond = new DocumentContentPage(userSecondPage)
await documentContentPageSecond.confirmApproval()
await documentContentPageSecond.checkDocumentStatus(DocumentStatus.EFFECTIVE)
await documentContentPageSecond.checkDocument({
...documentDetails,
status: DocumentStatus.EFFECTIVE,
version: 'v0.1'
})
await documentContentPageSecond.checkCurrentRights(DocumentRights.VIEWING)
await attachScreenshot('TESTS-271_approve_document.png', page)
})
await test.step('4. Download PDF', async () => {
await attachScreenshot('TESTS-271-check_content.png', page)
})
})
})

View File

@ -0,0 +1,119 @@
import { test } from '@playwright/test'
import { attachScreenshot, generateId, HomepageURI, PlatformSetting, PlatformURI } from '../utils'
import { allure } from 'allure-playwright'
import { DocumentContentPage } from '../model/documents/document-content-page'
import { LeftSideMenuPage } from '../model/left-side-menu-page'
import { faker } from '@faker-js/faker'
import { createTemplateStep } from './common-documents-steps'
test.use({
storageState: PlatformSetting
})
test.describe('ISO 13485, 4.2.4 Control of documents', () => {
test.beforeEach(async ({ page }) => {
await (await page.goto(`${PlatformURI}/${HomepageURI}`))?.finished()
})
test('TESTS-298. Create a new Category from top right corner', async ({ page }) => {
await allure.description('Requirement\nUsers need to create a new category')
await allure.tms('TESTS-298', 'https://tracex.hc.engineering/workbench/platform/tracker/TESTS-298')
const title = faker.word.words(2)
const description = faker.lorem.sentence(1)
const code = faker.word.words(2)
const leftSideMenuPage = new LeftSideMenuPage(page)
await leftSideMenuPage.clickButtonOnTheLeft('Documents')
await test.step('2. Create a new category', async () => {
const documentContentPage = new DocumentContentPage(page)
await documentContentPage.selectControlDocumentSubcategory('Categories')
await documentContentPage.clickOnAddCategoryButton()
await documentContentPage.fillCategoryForm(title, description, code)
await documentContentPage.checkIfCategoryIsCreated(title, code)
})
await attachScreenshot('TESTS-298_category_created.png', page)
})
test('TESTS-381. As a workspace user, I can create a new space and label it External Doc', async ({ page }) => {
await allure.description('Requirement\nUsers need to create a new space')
await allure.tms('TESTS-381', 'https://tracex.hc.engineering/workbench/platform/tracker/TESTS-381')
const leftSideMenuPage = new LeftSideMenuPage(page)
const folderName = generateId(5)
await leftSideMenuPage.clickButtonOnTheLeft('Documents')
await test.step('2. Create a new document space', async () => {
const documentContentPage = new DocumentContentPage(page)
await documentContentPage.clickAddFolderButton()
await documentContentPage.fillDocumentSpaceForm(folderName)
await documentContentPage.checkSpaceFormIsCreated(folderName)
await documentContentPage.clickLeaveFolder(folderName)
})
await attachScreenshot('TESTS-381_document_space_created.png', page)
})
test('TESTS-382. Create new a new Effective Template with category External', async ({ page }) => {
await allure.description('Requirement\nUsers need to create a new template')
await allure.tms('TESTS-382', 'https://tracex.hc.engineering/workbench/platform/tracker/TESTS-382')
const leftSideMenuPage = new LeftSideMenuPage(page)
const category = faker.word.words(2)
const description = faker.lorem.sentence(1)
const code = faker.word.words(2)
const title = faker.word.words(2)
await leftSideMenuPage.clickButtonOnTheLeft('Documents')
await test.step('2. Create a new category', async () => {
const documentContentPage = new DocumentContentPage(page)
await documentContentPage.selectControlDocumentSubcategory('Categories')
await documentContentPage.clickOnAddCategoryButton()
await documentContentPage.fillCategoryForm(category, description, code)
await documentContentPage.checkIfCategoryIsCreated(category, code)
})
await test.step('3. Create a new template', async () => {
const documentContentPage = new DocumentContentPage(page)
await documentContentPage.clickNewDocumentArrow()
await documentContentPage.clickNewTemplate()
await createTemplateStep(page, title, description, category)
})
await attachScreenshot('TESTS-382_Template_created.png', page)
})
test('TESTS-383. authorized User can search a doc per category "External"', async ({ page }) => {
await allure.description('Requirement\nUsers need to create a new category and space')
await allure.tms('TESTS-383', 'https://tracex.hc.engineering/workbench/platform/tracker/TESTS-383')
const title = faker.word.words(2)
const description = faker.lorem.sentence(1)
const code = faker.word.words(2)
const leftSideMenuPage = new LeftSideMenuPage(page)
const category = faker.word.words(2)
await leftSideMenuPage.clickButtonOnTheLeft('Documents')
await test.step('2. Create a new category', async () => {
const documentContentPage = new DocumentContentPage(page)
await documentContentPage.selectControlDocumentSubcategory('Categories')
await documentContentPage.clickOnAddCategoryButton()
await documentContentPage.fillCategoryForm(category, description, code)
await documentContentPage.checkIfCategoryIsCreated(category, code)
})
await test.step('3. Create a new template', async () => {
const documentContentPage = new DocumentContentPage(page)
await documentContentPage.clickNewDocumentArrow()
await documentContentPage.clickNewTemplate()
await createTemplateStep(page, title, description, category)
})
await test.step('4. Check if templates exists in template category', async () => {
const documentContentPage = new DocumentContentPage(page)
await documentContentPage.selectControlDocumentSubcategory('Templates')
await documentContentPage.chooseFilter(code)
await documentContentPage.checkIfFilterIsApplied(title)
})
await attachScreenshot('TESTS-383_Template_created.png', page)
})
})

View File

@ -18,6 +18,19 @@ export async function prepareDocumentStep (page: Page, document: NewDocument, st
})
}
export async function createTemplateStep (
page: Page,
title: string,
description: string,
category: string
): Promise<void> {
await test.step('2. Create a new template', async () => {
const documentsPage = new DocumentsPage(page)
await documentsPage.createTemplate(title, description, category)
})
}
export async function prepareCategoryStep (page: Page, newCategory: NewCategory): Promise<void> {
await test.step('1. Create a new category', async () => {
const leftSideMenuPage = new LeftSideMenuPage(page)

View File

@ -58,6 +58,20 @@ export class DocumentContentPage extends DocumentCommonPage {
readonly buttonHistoryTab: Locator
readonly documentHeader: Locator
readonly leaveFolder: Locator
readonly textContainer: Locator
readonly myDocument: Locator
readonly library: Locator
readonly templates: Locator
readonly categories: Locator
readonly addCategoryButton: Locator
readonly categoryTitle: Locator
readonly description: Locator
readonly categoryCode: Locator
readonly generalDocumentation: Locator
readonly newDocumentArrow: Locator
readonly newTemplate: Locator
readonly filter: Locator
readonly filterCategory: Locator
constructor (page: Page) {
super(page)
@ -126,6 +140,20 @@ export class DocumentContentPage extends DocumentCommonPage {
this.buttonHistoryTab = page.getByText('History')
this.documentHeader = page.getByRole('button', { name: 'Complete document' })
this.leaveFolder = page.getByRole('button', { name: 'Leave' })
this.textContainer = page.locator('.tiptap')
this.myDocument = page.getByRole('button', { name: 'Categories' })
this.library = page.getByRole('button', { name: 'Library' })
this.templates = page.getByRole('button', { name: 'Templates' })
this.categories = page.getByRole('button', { name: 'Categories' })
this.addCategoryButton = page.getByRole('button', { name: 'Category', exact: true })
this.categoryTitle = page.getByPlaceholder('Title')
this.description = page.getByRole('paragraph')
this.categoryCode = page.getByPlaceholder('Code')
this.generalDocumentation = page.getByRole('button', { name: 'General documentation' })
this.newDocumentArrow = page.locator('.w-full > button:nth-child(2)')
this.newTemplate = page.getByRole('button', { name: 'New template', exact: true })
this.filter = page.getByRole('button', { name: 'Filter' })
this.filterCategory = page.locator('span').filter({ hasText: /^Category$/ })
}
async checkDocumentTitle (title: string): Promise<void> {
@ -144,6 +172,62 @@ export class DocumentContentPage extends DocumentCommonPage {
.fill(title)
}
async clickOnAddCategoryButton (): Promise<void> {
await this.addCategoryButton.click()
}
async clickNewDocumentArrow (): Promise<void> {
await this.newDocumentArrow.click()
}
async clickNewTemplate (): Promise<void> {
await this.newTemplate.click()
}
async selectControlDocumentSubcategory (
buttonName: 'My Document' | 'Library' | 'Templates' | 'Categories' | 'General documentation'
): Promise<void> {
switch (buttonName) {
case 'My Document':
await this.myDocument.click()
break
case 'Library':
await this.library.click()
break
case 'Templates':
await this.templates.click()
break
case 'Categories':
await this.categories.click()
break
case 'General documentation':
await this.generalDocumentation.click()
break
default:
throw new Error('Unknown button')
}
}
async fillCategoryForm (categoryTitle: string, description: string, categoryCode: string): Promise<void> {
await this.categoryTitle.fill(categoryTitle)
await this.description.fill(description)
await this.categoryCode.fill(categoryCode)
await this.createButton.click()
}
async checkIfCategoryIsCreated (categoryTitle: string, categoryCode: string): Promise<void> {
await expect(this.page.getByText(categoryTitle)).toBeVisible()
await expect(this.page.getByRole('link', { name: categoryCode })).toBeVisible()
}
async checkIfTextExists (text: string): Promise<void> {
await expect(this.textContainer).toContainText(text)
}
async hoverOverGeneralDocumentation (): Promise<void> {
await this.generalDocumentation.hover()
}
async addReasonAndImpactToTheDocument (description: string, reason: string): Promise<void> {
await this.page.getByText('Reason & Impact').click()
await this.page.getByPlaceholder('Describe what was changed...').fill(description)
@ -199,15 +283,34 @@ export class DocumentContentPage extends DocumentCommonPage {
await this.addSpaceButton.click()
}
async chooseFilter (category: string): Promise<void> {
await this.filter.click()
await this.filterCategory.hover()
await this.page.getByRole('button', { name: 'Category', exact: true }).click()
await this.page.getByText(category).click({ force: true })
await this.page.keyboard.press('Escape')
}
async checkIfFilterIsApplied (code: string): Promise<void> {
await expect(this.page.getByText(code, { exact: true })).toBeVisible()
}
async fillDocumentSpaceForm (spaceName: string): Promise<void> {
await this.inputSpaceName.fill(spaceName)
await this.roleSelector.nth(2).click()
await this.selectRoleMember.nth(2).click()
await this.page.keyboard.press('Escape')
await this.selectRoleMember.nth(1).click()
await this.page.getByRole('button', { name: 'DK Dirak Kainin' }).click()
await this.page.keyboard.press('Escape')
await this.page.waitForTimeout(1000)
await this.createButton.click()
}
async checkSpaceFormIsCreated (spaceName: string): Promise<void> {
await expect(this.page.getByRole('button', { name: spaceName })).toBeVisible()
}
async createNewDocumentInsideFolder (folderName: string): Promise<void> {
await this.page.getByRole('button', { name: folderName }).hover()
await this.page.getByRole('button', { name: folderName }).getByRole('button').click()

View File

@ -10,6 +10,11 @@ export class DocumentsPage extends CalendarPage {
readonly inputNewDocumentTitle: Locator
readonly inputNewDocumentDescription: Locator
readonly inputNewDocumentCreateDaft: Locator
readonly category: Locator
readonly search: Locator
readonly nextStep: Locator
readonly addMember: Locator
readonly newMember: Locator
constructor (page: Page) {
super(page)
@ -23,6 +28,13 @@ export class DocumentsPage extends CalendarPage {
this.inputNewDocumentTitle = page.locator('div[id="doc-title"] input')
this.inputNewDocumentDescription = page.locator('div[id="doc-description"] input')
this.inputNewDocumentCreateDaft = page.locator('div.footer div.footerButtons button[type="button"]')
this.category = page.locator(
"xpath=//button[@class='antiButton no-border small jf-center sh-no-shape bs-solid gap-medium iconR']"
)
this.search = page.getByPlaceholder('Search...')
this.nextStep = page.getByRole('button', { name: 'Next step' })
this.addMember = page.getByText('Add member')
this.newMember = page.getByRole('button', { name: 'AJ Appleseed John' })
}
async createDocument (data: NewDocument, startSecondStep: boolean = false): Promise<void> {
@ -54,6 +66,20 @@ export class DocumentsPage extends CalendarPage {
await this.inputNewDocumentCreateDaft.click()
}
async createTemplate (title: string, description: string, category: string): Promise<void> {
await this.buttonPopupNextStep.click()
await this.inputNewDocumentTitle.fill(title)
await this.inputNewDocumentDescription.fill(description)
await this.category.click()
await this.search.fill(category)
await this.page.getByRole('button', { name: category }).click()
await this.nextStep.click()
await this.addMember.nth(2).click()
await this.newMember.click()
await this.page.keyboard.press('Escape')
await this.inputNewDocumentCreateDaft.click()
}
async openDocument (name: string): Promise<void> {
await this.page.locator('button.hulyNavItem-container > span[class*="label"]', { hasText: name }).click()
}

View File

@ -12,4 +12,20 @@ export class LeftSideMenuPage {
this.buttonTeam = page.locator('button[id$="Team"]')
this.buttonDocuments = page.locator('[id$="app-documents\\:string\\:DocumentApplication"]')
}
async clickButtonOnTheLeft (buttonName: 'Planning' | 'Team' | 'Documents'): Promise<void> {
switch (buttonName) {
case 'Planning':
await this.buttonPlanning.click()
break
case 'Team':
await this.buttonTeam.click()
break
case 'Documents':
await this.buttonDocuments.click()
break
default:
throw new Error('Unknown button')
}
}
}

View File

@ -28,7 +28,8 @@ const config: PlaywrightTestConfig = {
contextOptions: {
reducedMotion: 'reduce'
}
}
},
fullyParallel: false
}
],
retries: 2,