Visual check for PDF (#6599)

Signed-off-by: Jasmin <jasmin@hardcoreeng.com>
This commit is contained in:
JasminMus 2024-10-16 12:18:38 +02:00 committed by GitHub
parent 5061856f12
commit 1d3299e384
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
28 changed files with 1116 additions and 20 deletions

View File

@ -14,6 +14,9 @@
# Create third user record in accounts
./tool-local.sh create-account user3 -f Cain -l Velasquez -p 1234
./tool-local.sh confirm-email user3
# Create fourth user record in accounts
./tool-local.sh create-account user4 -f Armin -l Karmin -p 1234
./tool-local.sh confirm-email user4
./tool-local.sh create-account user_qara -f Qara -l Admin -p 1234
./tool-local.sh confirm-email user_qara

View File

@ -28,14 +28,16 @@ fi
./tool.sh create-account user1 -f John -l Appleseed -p 1234
./tool.sh create-account user2 -f Kainin -l Dirak -p 1234
./tool.sh create-account user3 -f Cain -l Velasquez -p 1234
./tool.sh create-account user4 -f Armin -l Karmin -p 1234
./tool.sh assign-workspace user1 sanity-ws-qms
./tool.sh assign-workspace user2 sanity-ws-qms
./tool.sh assign-workspace user3 sanity-ws-qms
./tool.sh assign-workspace user4 sanity-ws-qms
# Make user the workspace maintainer
./tool.sh confirm-email user1
./tool.sh confirm-email user2
./tool.sh confirm-email user3
./tool.sh confirm-email user4
./tool.sh create-account user_qara -f Qara -l Admin -p 1234
./tool.sh assign-workspace user_qara sanity-ws-qms

View File

@ -15,6 +15,7 @@ export SERVER_SECRET=secret
./tool-local.sh assign-workspace user1 sanity-ws-qms
./tool-local.sh assign-workspace user2 sanity-ws-qms
./tool-local.sh assign-workspace user3 sanity-ws-qms
./tool-local.sh assign-workspace user4 sanity-ws-qms
./tool-local.sh assign-workspace user_qara sanity-ws-qms
./tool-local.sh set-user-role user1 sanity-ws-qms OWNER

View File

@ -9,6 +9,7 @@
./tool.sh assign-workspace user1 sanity-ws-qms
./tool.sh assign-workspace user2 sanity-ws-qms
./tool.sh assign-workspace user3 sanity-ws-qms
./tool.sh assign-workspace user4 sanity-ws-qms
./tool.sh set-user-role user2 sanity-ws-qms OWNER
./tool.sh assign-workspace user_qara sanity-ws-qms

View File

@ -19,9 +19,10 @@
"format": "format tests",
"ci": "playwright install --with-deps chromium",
"test": "",
"uitest": "cross-env LOCAL_URL=http://host.docker.internal:3003/ DEV_URL= playwright test -c ./tests/playwright.config.ts",
"staging-uitest": "cross-env PLATFORM_URI=https://front.hc.engineering/ playwright test -c ./tests/playwright.config.ts --grep @staging",
"dev-uitest": "cross-env PLATFORM_URI=http://localhost:8080 PLATFORM_TRANSACTOR=ws://host.docker.internal:3333 SETTING=storage-dev.json SETTING_SECOND=storageSecond-dev.json DEV_URL=http://localhost:8080/account playwright test -c ./tests/playwright.config.ts",
"uitest": "cross-env LOCAL_URL=http://host.docker.internal:3003/ DEV_URL= playwright test -c ./tests/playwright.config.ts --grep-invert @PDF",
"uitest-pdf": "cross-env LOCAL_URL=http://host.docker.internal:3003/ DEV_URL= playwright test -c ./tests/playwright.config.ts --grep @PDF",
"staging-uitest": "cross-env PLATFORM_URI=https://front.hc.engineering/ playwright test -c ./tests/playwright.config.ts --grep @staging --grep-invert @PDF",
"dev-uitest": "cross-env PLATFORM_URI=http://localhost:8080 PLATFORM_TRANSACTOR=ws://host.docker.internal:3333 SETTING=storage-dev.json SETTING_SECOND=storageSecond-dev.json DEV_URL=http://localhost:8080/account playwright test -c ./tests/playwright.config.ts --grep-invert @PDF",
"debug": "playwright test -c ./tests/playwright.config.ts --debug --headed",
"dev-debug": "cross-env PLATFORM_URI=http://localhost:8080 PLATFORM_TRANSACTOR=ws://host.docker.internal:3333 SETTING=storage-dev.json SETTING_SECOND=storageSecond-dev.json playwright test -c ./tests/playwright.config.ts --debug --headed",
"codegen": "playwright codegen --load-storage storage.json http://host.docker.internal:8083/workbench/sanity-ws/",

View File

@ -0,0 +1,38 @@
{
"cookies": [],
"origins": [
{
"origin": "http://localhost:8080",
"localStorage": [
{
"name": "login:metadata:LoginEmail",
"value": "user4"
},
{
"name": "login:metadata:LoginTokens",
"value": "{\"sanity-ws-qms\":\"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJjb25maXJtZWQiOnRydWUsImVtYWlsIjoidXNlcjQiLCJ3b3Jrc3BhY2UiOiIifQ.ww1aIf8yrNtS2a7nlLuq0EF2zKN04ThDHp5nSMwhj80\"}"
},
{
"name": "login:metadata:LoginEndpoint",
"value": "ws://localhost:3334"
},
{
"name": "#platform.notification.logging",
"value": "false"
},
{
"name": "#platform.lazy.loading",
"value": "false"
},
{
"name": "flagOpenInDesktopApp",
"value": "true"
},
{
"name": "#platform.notification.timeout",
"value": "0"
}
]
}
]
}

View File

@ -0,0 +1,38 @@
{
"cookies": [],
"origins": [
{
"origin": "http://host.docker.internal:8083",
"localStorage": [
{
"name": "login:metadata:LoginEmail",
"value": "user4"
},
{
"name": "login:metadata:LoginTokens",
"value": "{\"sanity-ws-qms\":\"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJjb25maXJtZWQiOnRydWUsImVtYWlsIjoidXNlcjQiLCJ3b3Jrc3BhY2UiOiIifQ.ww1aIf8yrNtS2a7nlLuq0EF2zKN04ThDHp5nSMwhj80\"}"
},
{
"name": "login:metadata:LoginEndpoint",
"value": "ws://host.docker.internal:3334"
},
{
"name": "#platform.notification.logging",
"value": "false"
},
{
"name": "#platform.lazy.loading",
"value": "false"
},
{
"name": "flagOpenInDesktopApp",
"value": "true"
},
{
"name": "#platform.notification.timeout",
"value": "0"
}
]
}
]
}

View File

@ -0,0 +1,101 @@
import { devices, test } from '@playwright/test'
import { attachScreenshot, HomepageURI, PlatformSetting, PlatformURI, waitForNetworIdle } from '../utils'
import { allure } from 'allure-playwright'
import { DocumentDetails, DocumentRights, DocumentStatus, NewDocument } from '../model/types'
import { DocumentContentPage } from '../model/documents/document-content-page'
import { prepareDocumentStep } from './common-documents-steps'
import { DocumentApprovalsPage } from '../model/documents/document-approvals-page'
import { PdfPages } from '../model/documents/pdf-pages'
import { VisualCheck } from '../model/visual-check'
test.use({
storageState: PlatformSetting,
...devices['Desktop Edge'],
channel: 'msedge'
})
test.describe('@PDF. QMS. PDF Download and Preview', () => {
test.beforeEach(async ({ page }) => {
await (await page.goto(`${PlatformURI}/${HomepageURI}`))?.finished()
})
test.afterEach(async ({ browser }) => {
const contexts = browser.contexts()
for (const context of contexts) {
await context.close()
}
})
test('TESTS-277 - @PDF Author can Generate PDF from a doc with all Reviewers and Approvers signature info displayed', async ({
page
}) => {
await allure.description('Requirement\nUsers need to review the document and review status is displayed in PDF')
await allure.tms('TESTS-277', 'https://tracex.hc.engineering/workbench/platform/tracker/TESTS-277')
const approveDocument: NewDocument = {
template: 'HR (HR)',
title: 'Approve document-Test',
description: 'Approve document description-Test'
}
const documentDetails: DocumentDetails = {
type: 'HR',
category: 'Human Resources',
version: 'v0.1',
status: DocumentStatus.DRAFT,
owner: 'Appleseed John',
author: 'Appleseed John'
}
await prepareDocumentStep(page, approveDocument)
const documentContentPage = new DocumentContentPage(page)
await test.step('2. Add reviewers from team', async () => {
await documentContentPage.addReviewersFromTeam()
await documentContentPage.sendForReview()
await documentContentPage.completeReview()
})
await test.step('3. Send for Approval', async () => {
await documentContentPage.buttonSendForApproval.click()
await documentContentPage.fillSelectApproversForm([documentDetails.owner])
await documentContentPage.checkDocumentStatus(DocumentStatus.IN_APPROVAL)
await documentContentPage.checkDocument({
...documentDetails,
status: DocumentStatus.IN_APPROVAL
})
await documentContentPage.checkCurrentRights(DocumentRights.VIEWING)
})
await test.step('4. Approve document', async () => {
await documentContentPage.confirmApproval()
})
await test.step('5. Check the document and status', async () => {
await documentContentPage.checkDocumentStatus(DocumentStatus.EFFECTIVE)
await documentContentPage.checkDocument({
...documentDetails,
status: DocumentStatus.EFFECTIVE,
version: 'v0.1'
})
await documentContentPage.checkCurrentRights(DocumentRights.VIEWING)
await documentContentPage.openApprovals()
const documentApprovalsPage = new DocumentApprovalsPage(page)
await documentApprovalsPage.checkSuccessApproval(documentDetails.owner)
await attachScreenshot('TESTS-277_approve_document.png', page)
})
await test.step('6. Show Full screen preview', async () => {
await documentContentPage.clickDocumentThreeDots()
const pdfPages = new PdfPages(page)
await pdfPages.printToPdfClick()
await waitForNetworIdle(page)
await page.waitForTimeout(2000)
await pdfPages.showFullScreenPdfClick()
await page.waitForTimeout(2000)
})
await test.step('7. Check PDF Preview', async () => {
const visualCheck = new VisualCheck(page)
await visualCheck.comparePDFPreview('TESTS-277_pdf_preview')
})
await attachScreenshot('TESTS-277_pdf_preview.png', page)
})
})

View File

@ -0,0 +1,29 @@
import { test } from '@playwright/test'
import { HomepageURI, PlatformSettingThird, PlatformURI } from '../utils'
import { allure } from 'allure-playwright'
import { DocumentContentPage } from '../model/documents/document-content-page'
test.use({
storageState: PlatformSettingThird
})
test.describe('ISO 13485, 4.2.4 Control of documents ensure that documents of external origin are identified and their distribution controlled', () => {
test.beforeEach(async ({ page }) => {
await (await page.goto(`${PlatformURI}/${HomepageURI}`))?.finished()
})
test('TESTS-389. As a non workspace owner, I cannot remove a user from workspace', async ({ page }) => {
await allure.description(
'Requirement\nUser is not a part of space members and cannot see or edit any document from that space'
)
await allure.tms('TESTS-389', 'https://tracex.hc.engineering/workbench/platform/tracker/TESTS-389')
await test.step('2. check if non member can kick user from space', async () => {
const documentContentPage = new DocumentContentPage(page)
await documentContentPage.clickContacts()
await documentContentPage.clickEmployee()
await documentContentPage.selectEmployee('AQ Admin Qara')
await documentContentPage.clickEmployeeDropdown()
await documentContentPage.checkIfUserCanKick()
})
})
})

View File

@ -0,0 +1,35 @@
import { test } from '@playwright/test'
import { PlatformUser } from '../utils'
import { LoginPage } from '../model/login-page'
test.describe('login test', () => {
let loginPage: LoginPage
test.beforeEach(async ({ page }) => {
loginPage = new LoginPage(page)
await loginPage.goto()
})
test('check login', async () => {
await loginPage.clickOnLoginWithPassword()
await loginPage.login(PlatformUser, '1234')
})
test('TESTS-392 - As a non workspace user account I cannot log into TraceX', async () => {
await loginPage.clickOnLoginWithPassword()
await loginPage.login('Wrong User', 'Wrong password')
await loginPage.checkIfErrorMessageIsShown('Account not found')
})
test('TESTS-396 - Correct email and wrong password: I cannot log in', async () => {
await loginPage.clickOnLoginWithPassword()
await loginPage.login(PlatformUser, 'Wrong password')
await loginPage.checkIfErrorMessageIsShown('Invalid password')
})
test('TESTS-397 - Wrong email and correct password: I cannot log in', async () => {
await loginPage.clickOnLoginWithPassword()
await loginPage.login('Wrong User', '1234')
await loginPage.checkIfErrorMessageIsShown('Account not found')
})
})

View File

@ -0,0 +1,54 @@
import { test } from '@playwright/test'
import { attachScreenshot, HomepageURI, PlatformSettingSecond, PlatformURI, waitForNetworIdle } from '../utils'
import { allure } from 'allure-playwright'
import { DocumentContentPage } from '../model/documents/document-content-page'
import { faker } from '@faker-js/faker'
test.use({
storageState: PlatformSettingSecond
})
test.describe('ISO 13485, 4.2.4 Control of documents ensure that documents of external origin are identified and their distribution controlled', () => {
test.beforeEach(async ({ page }) => {
await (await page.goto(`${PlatformURI}/${HomepageURI}`))?.finished()
})
test('TESTS-391. As a non space member, I cannot see nor edit any doc from that space', async ({ page }) => {
await allure.description(
'Requirement\nUser is not a part of space members and cannot see or edit any document from that space'
)
await allure.tms('TESTS-391', 'https://tracex.hc.engineering/workbench/platform/tracker/TESTS-391')
await test.step('2. check if non member can see space', async () => {
const folderName = faker.word.words(1)
const documentContentPage = new DocumentContentPage(page)
await documentContentPage.clickAddFolderButton()
await documentContentPage.fillDocumentSpaceFormManager(folderName)
await documentContentPage.changeDocumentSpaceMembers(folderName)
await documentContentPage.checkIfTheSpaceIsVisible(folderName, false)
await documentContentPage.clickDocumentsSpace()
await waitForNetworIdle(page)
await documentContentPage.clickOnTeamspaceOrArrow()
await documentContentPage.fillTeamspaceFormManager(folderName)
await documentContentPage.changeTeamspaceMembers(folderName)
await documentContentPage.checkIfTheSpaceIsVisible(folderName, false)
await attachScreenshot('TESTS-391_space_not_existing.png', page)
})
})
test('TESTS-388. As a workspace owner, I can remove a user from workspace', async ({ page }) => {
await allure.description(
'Requirement\nUser is not a part of space members and cannot see or edit any document from that space'
)
await allure.tms('TESTS-388', 'https://tracex.hc.engineering/workbench/platform/tracker/TESTS-388')
await test.step('2. check if owner can kick user from workspace', async () => {
const documentContentPage = new DocumentContentPage(page)
await documentContentPage.clickContacts()
await documentContentPage.clickEmployee()
await documentContentPage.selectEmployee('KA Karmin Armin')
await documentContentPage.clickEmployeeDropdown()
await documentContentPage.clickKickEmployee()
await documentContentPage.clickConfirmKickEmployee()
await documentContentPage.checkIfEmployeeIsKicked('Karmin Armin')
})
})
})

View File

@ -0,0 +1,289 @@
import { devices, test } from '@playwright/test'
import {
attachScreenshot,
DocumentURI,
generateId,
getSecondPage,
HomepageURI,
PlatformSetting,
PlatformURI
} from '../utils'
import { allure } from 'allure-playwright'
import { DocumentDetails, DocumentRights, DocumentStatus, NewDocument } from '../model/types'
import { DocumentContentPage } from '../model/documents/document-content-page'
import { prepareDocumentStep } from './common-documents-steps'
import { DocumentApprovalsPage } from '../model/documents/document-approvals-page'
import { PdfPages } from '../model/documents/pdf-pages'
import { VisualCheck } from '../model/visual-check'
import { DocumentsPage } from '../model/documents/documents-page'
test.use({
storageState: PlatformSetting,
...devices['Desktop Edge'],
channel: 'msedge'
})
test.describe('QMS. PDF Download and Preview', () => {
test.beforeEach(async ({ page }) => {
await (await page.goto(`${PlatformURI}/${HomepageURI}`))?.finished()
})
test.afterEach(async ({ browser }) => {
const contexts = browser.contexts()
for (const context of contexts) {
await context.close()
}
})
test('TESTS-386 - @PDF Author can Generate PDF from a doc with all Reviewers and Approvers signature info displayed', async ({
page,
browser
}) => {
await allure.description('Requirement\nUsers need to review the document and review status is displayed in PDF')
await allure.tms('TESTS-386', 'https://tracex.hc.engineering/workbench/platform/tracker/TESTS-386')
const userSecondPage = await getSecondPage(browser)
const approveDocument: NewDocument = {
template: 'HR (HR)',
title: 'This is a test document QMS TESTS-386',
description: 'This is a test document description'
}
const documentDetails: DocumentDetails = {
type: 'HR',
category: 'Human Resources',
version: 'v0.1',
status: DocumentStatus.DRAFT,
owner: 'Appleseed John',
author: 'Appleseed John'
}
await prepareDocumentStep(page, approveDocument)
const documentContentPage = new DocumentContentPage(page)
await test.step('2. Add reviewers from team', async () => {
await documentContentPage.addReviewersFromTeam(true)
await documentContentPage.sendForReview()
await documentContentPage.completeReview()
})
await test.step('3. Send for Approval', async () => {
await (await userSecondPage.goto(`${PlatformURI}/${DocumentURI}`))?.finished()
const documentContentPageSecond = new DocumentContentPage(userSecondPage)
const documentsPageSecond = new DocumentsPage(userSecondPage)
await documentsPageSecond.openDocument(approveDocument.title)
await documentContentPageSecond.completeReview()
await documentsPageSecond.openDocument(approveDocument.title)
await documentContentPage.buttonSendForApproval.click()
await documentContentPage.fillSelectApproversForm([documentDetails.owner])
await documentContentPage.checkDocumentStatus(DocumentStatus.IN_APPROVAL)
await documentContentPage.checkDocument({
...documentDetails,
status: DocumentStatus.IN_APPROVAL
})
await documentContentPage.checkCurrentRights(DocumentRights.VIEWING)
})
await test.step('4. Approve document', async () => {
await documentContentPage.confirmApproval()
})
await test.step('5. Check the document and status', async () => {
await documentContentPage.checkDocumentStatus(DocumentStatus.EFFECTIVE)
await documentContentPage.checkDocument({
...documentDetails,
status: DocumentStatus.EFFECTIVE,
version: 'v0.1'
})
await documentContentPage.checkCurrentRights(DocumentRights.VIEWING)
await documentContentPage.openApprovals()
const documentApprovalsPage = new DocumentApprovalsPage(page)
await documentApprovalsPage.checkSuccessApproval(documentDetails.owner)
await attachScreenshot('TESTS-386_approve_document.png', page)
})
const documentsPageSecond = new DocumentsPage(userSecondPage)
await documentsPageSecond.openDocument(approveDocument.title)
await test.step('6. Show Full screen preview', async () => {
const pdfPagesSecondPage = new PdfPages(userSecondPage)
const documentContentPageSecond = new DocumentContentPage(userSecondPage)
await documentContentPageSecond.clickDocumentThreeDots()
await pdfPagesSecondPage.printToPdfClick()
await userSecondPage.waitForTimeout(2000)
await pdfPagesSecondPage.showFullScreenPdfClick()
await userSecondPage.waitForTimeout(2000)
})
await test.step('7. Check PDF Preview', async () => {
const visualCheckSecondPage = new VisualCheck(userSecondPage)
await visualCheckSecondPage.comparePDFPreview('TESTS-386_pdf_preview')
})
await attachScreenshot('TESTS-386.png', page)
})
test('TESTS-387 - @PDF Author can Generate PDF from a doc with all Reviewers and Approvers signature info displayed', async ({
page,
browser
}) => {
await allure.description('Requirement\nUsers need to review the document and review status is displayed in PDF')
await allure.tms('TESTS-387', 'https://tracex.hc.engineering/workbench/platform/tracker/TESTS-387')
const userSecondPage = await getSecondPage(browser)
const approveDocument: NewDocument = {
template: 'HR (HR)',
title: 'This is a test for a QMS TESTS-387',
description: 'This is a test document description'
}
const documentDetails: DocumentDetails = {
type: 'HR',
category: 'Human Resources',
version: 'v0.1',
status: DocumentStatus.DRAFT,
owner: 'Appleseed John',
author: 'Appleseed John'
}
await prepareDocumentStep(page, approveDocument)
const documentContentPage = new DocumentContentPage(page)
await test.step('2. Add reviewers from team', async () => {
await documentContentPage.addReviewersFromTeam(false)
await documentContentPage.addApproversFromTeam()
await documentContentPage.buttonSendForApproval.click()
await documentContentPage.fillSelectApproversForm([documentDetails.owner])
await documentContentPage.checkDocumentStatus(DocumentStatus.IN_APPROVAL)
await documentContentPage.checkDocument({
...documentDetails,
status: DocumentStatus.IN_APPROVAL
})
await documentContentPage.checkCurrentRights(DocumentRights.VIEWING)
await documentContentPage.confirmApproval()
})
await test.step('4. Send for Approval', async () => {
await (await userSecondPage.goto(`${PlatformURI}/${DocumentURI}`))?.finished()
const documentContentPageSecond = new DocumentContentPage(userSecondPage)
const documentsPageSecond = new DocumentsPage(userSecondPage)
await documentsPageSecond.openDocument(approveDocument.title)
await documentContentPageSecond.clickApproveButtonAndFillPassword()
// await documentContentPageSecond.completeReview()
await documentsPageSecond.openDocument(approveDocument.title)
})
await test.step('7. Show Full screen preview', async () => {
const documentsPageSecond = new DocumentsPage(userSecondPage)
const pdfPagesSecondPage = new PdfPages(userSecondPage)
await documentsPageSecond.openDocument(approveDocument.title)
const documentContentPageSecond = new DocumentContentPage(userSecondPage)
await documentContentPageSecond.clickDocumentThreeDots()
await pdfPagesSecondPage.printToPdfClick()
await userSecondPage.waitForTimeout(2000)
await pdfPagesSecondPage.showFullScreenPdfClick()
await userSecondPage.waitForTimeout(2000)
})
await test.step('8. Check PDF Preview', async () => {
const visualCheckSecondPage = new VisualCheck(userSecondPage)
await visualCheckSecondPage.comparePDFPreview('TESTS-387_pdf_preview')
})
await attachScreenshot('TESTS-387.png', page)
})
test('TESTS-393 - Doc Author, Reviewers, Approvers Electronic signature once doc is Effective', async ({
page,
browser
}) => {
await allure.description('Requirement\nUsers need to review the document and review status is displayed in PDF')
await allure.tms('TESTS-393', 'https://tracex.hc.engineering/workbench/platform/tracker/TESTS-393')
const userSecondPage = await getSecondPage(browser)
const approveDocument: NewDocument = {
template: 'HR (HR)',
title: `Complete document-${generateId()}`,
description: `Complete document description-${generateId()}`
}
const documentDetails: DocumentDetails = {
type: 'HR',
category: 'Human Resources',
version: 'v0.1',
status: DocumentStatus.DRAFT,
owner: 'Appleseed John',
author: 'Appleseed John'
}
await prepareDocumentStep(page, approveDocument)
const documentContentPage = new DocumentContentPage(page)
await test.step('2. Add reviewers from team', async () => {
await documentContentPage.addReviewersFromTeam(false)
await documentContentPage.addApproversFromTeam()
await documentContentPage.buttonSendForApproval.click()
await documentContentPage.fillSelectApproversForm([documentDetails.owner])
await documentContentPage.checkDocumentStatus(DocumentStatus.IN_APPROVAL)
await documentContentPage.checkIfLeftModalIsOpen()
await documentContentPage.checkDocument({
...documentDetails,
status: DocumentStatus.IN_APPROVAL
})
await documentContentPage.checkCurrentRights(DocumentRights.VIEWING)
await documentContentPage.confirmApproval()
})
await test.step('4. Send for Approval', async () => {
await (await userSecondPage.goto(`${PlatformURI}/${DocumentURI}`))?.finished()
const documentContentPageSecond = new DocumentContentPage(userSecondPage)
const documentsPageSecond = new DocumentsPage(userSecondPage)
await documentsPageSecond.openDocument(approveDocument.title)
await documentContentPageSecond.clickApproveButton()
await documentsPageSecond.openDocument(approveDocument.title)
})
await test.step('5. check if reviewers and approvers are visible', async () => {
const documentContentPageSecond = new DocumentContentPage(userSecondPage)
await documentContentPageSecond.clickOpenTeam()
await documentContentPageSecond.checkIfReviewersAndApproversAreVisible()
})
await attachScreenshot('TESTS-393.png', page)
})
test('TESTS-394 - Doc Author, Reviewers, Approvers Electronic signature once doc is Effective', async ({
page,
browser
}) => {
await allure.description('Requirement\nUsers need to review the document and review status is displayed in PDF')
await allure.tms('TESTS-394', 'https://tracex.hc.engineering/workbench/platform/tracker/TESTS-394')
const userSecondPage = await getSecondPage(browser)
const approveDocument: NewDocument = {
template: 'HR (HR)',
title: `Complete document-${generateId()}`,
description: `Complete document description-${generateId()}`
}
const documentDetails: DocumentDetails = {
type: 'HR',
category: 'Human Resources',
version: 'v0.1',
status: DocumentStatus.DRAFT,
owner: 'Appleseed John',
author: 'Appleseed John'
}
await prepareDocumentStep(page, approveDocument)
const documentContentPage = new DocumentContentPage(page)
await test.step('2. Add reviewers from team', async () => {
await documentContentPage.addReviewersFromTeam(false)
await documentContentPage.addApproversFromTeam()
await documentContentPage.buttonSendForApproval.click()
await documentContentPage.fillSelectApproversForm([documentDetails.owner])
await documentContentPage.checkDocumentStatus(DocumentStatus.IN_APPROVAL)
await documentContentPage.checkCurrentRights(DocumentRights.VIEWING)
await documentContentPage.confirmApproval()
})
await test.step('4. Send for Approval', async () => {
await (await userSecondPage.goto(`${PlatformURI}/${DocumentURI}`))?.finished()
const documentContentPageSecond = new DocumentContentPage(userSecondPage)
const documentsPageSecond = new DocumentsPage(userSecondPage)
await documentsPageSecond.openDocument(approveDocument.title)
await documentContentPageSecond.clickApproveButton()
await documentsPageSecond.openDocument(approveDocument.title)
})
await test.step('5. check if reviewers and approvers are visible', async () => {
const documentContentPageSecond = new DocumentContentPage(userSecondPage)
await documentContentPageSecond.clickOpenTeam()
await documentContentPageSecond.checkTheUserCantChangeReviewersAndApprovers()
})
await attachScreenshot('TESTS-394.png', page)
})
})

View File

@ -1,17 +1,20 @@
import { test } from '@playwright/test'
import { attachScreenshot, generateId, HomepageURI, PlatformSetting, PlatformURI } from '../utils'
import { devices, test } from '@playwright/test'
import { attachScreenshot, HomepageURI, PlatformSetting, PlatformURI } from '../utils'
import { allure } from 'allure-playwright'
import { DocumentDetails, DocumentRights, DocumentStatus, NewDocument } from '../model/types'
import { DocumentContentPage } from '../model/documents/document-content-page'
import { prepareDocumentStep } from './common-documents-steps'
import { DocumentApprovalsPage } from '../model/documents/document-approvals-page'
import { PdfPages } from '../model/documents/pdf-pages'
import { VisualCheck } from '../model/visual-check'
test.use({
storageState: PlatformSetting
storageState: PlatformSetting,
...devices['Desktop Edge'],
channel: 'msedge'
})
test.describe('QMS. PDF Download', () => {
test.describe('@PDF. QMS. PDF Download and Preview', () => {
test.beforeEach(async ({ page }) => {
await (await page.goto(`${PlatformURI}/${HomepageURI}`))?.finished()
})
@ -28,8 +31,8 @@ test.describe('QMS. PDF Download', () => {
await allure.tms('TESTS-271', 'https://tracex.hc.engineering/workbench/platform/tracker/TESTS-271')
const approveDocument: NewDocument = {
template: 'HR (HR)',
title: `Approve document-${generateId()}`,
description: `Approve document description-${generateId()}`
title: 'Approve document-Test',
description: 'Approve document description-Test}'
}
const documentDetails: DocumentDetails = {
type: 'HR',
@ -79,4 +82,157 @@ test.describe('QMS. PDF Download', () => {
})
await attachScreenshot('TESTS-271_ddownloaded_document.png', page)
})
test('TESTS-272. Check PDF Preview', async ({ page }) => {
await allure.description('Requirement\nUsers need to approve the document and check PDF preview')
await allure.tms('TESTS-271', 'https://tracex.hc.engineering/workbench/platform/tracker/TESTS-272')
const approveDocument: NewDocument = {
template: 'HR (HR)',
title: 'Approve document-Test 2}',
description: 'Approve document description-Test 2}'
}
const documentDetails: DocumentDetails = {
type: 'HR',
category: 'Human Resources',
version: 'v0.1',
status: DocumentStatus.DRAFT,
owner: 'Appleseed John',
author: 'Appleseed John'
}
await prepareDocumentStep(page, approveDocument)
const documentContentPage = new DocumentContentPage(page)
await test.step('2. Send for Approval', async () => {
await documentContentPage.buttonSendForApproval.click()
await documentContentPage.fillSelectApproversForm([documentDetails.owner])
await documentContentPage.checkDocumentStatus(DocumentStatus.IN_APPROVAL)
await documentContentPage.checkDocument({
...documentDetails,
status: DocumentStatus.IN_APPROVAL
})
await documentContentPage.checkCurrentRights(DocumentRights.VIEWING)
})
await test.step('3. Approve document', async () => {
await documentContentPage.confirmApproval()
})
await test.step('4. Check the document and status', async () => {
await documentContentPage.checkDocumentStatus(DocumentStatus.EFFECTIVE)
await documentContentPage.checkDocument({
...documentDetails,
status: DocumentStatus.EFFECTIVE,
version: 'v0.1'
})
await documentContentPage.checkCurrentRights(DocumentRights.VIEWING)
await documentContentPage.openApprovals()
const documentApprovalsPage = new DocumentApprovalsPage(page)
await documentApprovalsPage.checkSuccessApproval(documentDetails.owner)
await attachScreenshot('TESTS-272_approve_document.png', page)
})
await test.step('5. Show Full screen preview', async () => {
await documentContentPage.clickDocumentThreeDots()
const pdfPages = new PdfPages(page)
await pdfPages.printToPdfClick()
await page.waitForTimeout(2000)
await pdfPages.showFullScreenPdfClick()
await page.waitForTimeout(2000)
})
await test.step('6. Check PDF Preview', async () => {
const visualCheck = new VisualCheck(page)
await visualCheck.comparePDFPreview('TESTS-272_pdf_preview')
})
await attachScreenshot('TESTS-272_pdf_preview.png', page)
})
// This works fine but have no test case for it
test.skip('TESTS-273. Check PDF Preview', async ({ page, context }) => {
await allure.description('Requirement\nUsers need to approve the document and check PDF preview')
await allure.tms('TESTS-271', 'https://tracex.hc.engineering/workbench/platform/tracker/TESTS-273')
const approveDocument: NewDocument = {
template: 'HR (HR)',
title: 'Approve document-Test 3}',
description: 'Approve document description-Test 3}'
}
const documentDetails: DocumentDetails = {
type: 'HR',
category: 'Human Resources',
version: 'v0.1',
status: DocumentStatus.DRAFT,
owner: 'Appleseed John',
author: 'Appleseed John'
}
await prepareDocumentStep(page, approveDocument)
const documentContentPage = new DocumentContentPage(page)
await test.step('2. Send for Approval', async () => {
await documentContentPage.buttonSendForApproval.click()
await documentContentPage.fillSelectApproversForm([documentDetails.owner])
await documentContentPage.checkDocumentStatus(DocumentStatus.IN_APPROVAL)
await documentContentPage.checkDocument({ ...documentDetails, status: DocumentStatus.IN_APPROVAL })
await documentContentPage.checkCurrentRights(DocumentRights.VIEWING)
})
await test.step('3. Approve document', async () => {
await documentContentPage.confirmApproval()
})
await test.step('4. Check the document and status', async () => {
await documentContentPage.checkDocumentStatus(DocumentStatus.EFFECTIVE)
await documentContentPage.checkDocument({ ...documentDetails, status: DocumentStatus.EFFECTIVE, version: 'v0.1' })
await documentContentPage.checkCurrentRights(DocumentRights.VIEWING)
await documentContentPage.openApprovals()
const documentApprovalsPage = new DocumentApprovalsPage(page)
await documentApprovalsPage.checkSuccessApproval(documentDetails.owner)
await attachScreenshot('TESTS-271_approve_document.png', page)
})
await test.step('5. Download PDF', async () => {
await documentContentPage.clickDocumentThreeDots()
const pdfPages = new PdfPages(page)
await pdfPages.printToPdfClick()
// Wait for the iframe and log its presence
const iframe = await page
.waitForSelector('iframe[src*="PDF%20print%20preview"]', { timeout: 30000 })
.catch(() => null)
if (iframe === null || iframe === undefined) {
await attachScreenshot('TESTS-273_iframe_not_found.png', page)
throw new Error('iframe not found')
}
// Extract the URL from the iframe
const iframeURL = await iframe.getAttribute('src')
if (iframeURL !== null && iframeURL !== undefined) {
const newTab = await context.newPage()
try {
await newTab.goto(iframeURL, { timeout: 60000, waitUntil: 'domcontentloaded' })
await newTab.waitForTimeout(1000)
const visualCheck = new VisualCheck(newTab)
await visualCheck.compareScreenshot(null, 'TESTS-273_pdf_preview')
await newTab.close()
} catch (error) {
await attachScreenshot('TESTS-273_navigation_error.png', newTab)
await newTab.close()
throw error
}
} else {
throw new Error('URL not found in iframe')
}
})
await attachScreenshot('TESTS-273_final_state.png', page)
})
})

View File

@ -97,11 +97,11 @@ test.describe('ISO 13485, 4.2.4 Control of documents', () => {
})
})
test.skip('TESTS-271. Generate a PDF from an Effective doc', async ({ page, browser }) => {
test('TESTS-272. @PDF 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')
await allure.tms('TESTS-272', 'https://tracex.hc.engineering/workbench/platform/tracker/TESTS-272')
const userSecondPage = await getSecondPage(browser)
const completeDocument: NewDocument = {
@ -152,11 +152,7 @@ test.describe('ISO 13485, 4.2.4 Control of documents', () => {
})
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)
await attachScreenshot('TESTS-272_approve_document.png', page)
})
})
})

View File

@ -5,6 +5,7 @@ import { DocumentContentPage } from '../model/documents/document-content-page'
import { LeftSideMenuPage } from '../model/left-side-menu-page'
import { faker } from '@faker-js/faker'
import { SettingsPage } from '../model/setting-page'
test.use({
storageState: PlatformSetting
@ -60,4 +61,48 @@ test.describe('ISO 13485, 4.2.4 Control of documents', () => {
await attachScreenshot('TESTS-381_document_space_created.png', page)
})
test('TESTS-406. As a space member only, I cannot delete any doc from that space', async ({ page }) => {
await allure.description('Requirement\nUsers need to create a new space')
await allure.tms('TESTS-406', 'https://tracex.hc.engineering/workbench/platform/tracker/TESTS-406')
const leftSideMenuPage = new LeftSideMenuPage(page)
const folderName = generateId(5)
await leftSideMenuPage.clickButtonOnTheLeft('Documents')
await test.step('2. Create a new document space and check if user can create document', async () => {
const documentContentPage = new DocumentContentPage(page)
await documentContentPage.clickAddFolderButton()
await documentContentPage.fillDocumentAndSetMember(folderName)
await documentContentPage.checkIfUserCanCreateDocument(folderName)
})
await attachScreenshot('TESTS-406_user_cant_see_workspace.png', page)
})
test('TESTS-342. As a workspace owner, I can create roles and setup permissions', async ({ page }) => {
await allure.description(
'Requirement\nUser is the owner of the workspace and can create roles and setup permissions'
)
await allure.tms('TESTS-342', 'https://tracex.hc.engineering/workbench/platform/tracker/TESTS-342')
await test.step('2. Check user role and if the update permission is disabled', async () => {
const settingsPage = new SettingsPage(page)
await settingsPage.openProfileMenu()
await settingsPage.clickSettings()
await settingsPage.clickDefaultDocuments()
await settingsPage.chooseRole('Manager')
await settingsPage.checkIfPermissionsExist()
await settingsPage.checkIfAddUpdateDocumentOwnerPermissionIsDisabled()
await attachScreenshot('TESTS-342_Manager_roles.png', page)
await settingsPage.clickDefaultDocuments()
await settingsPage.chooseRole('QARA')
await settingsPage.checkIfPermissionsExist()
await settingsPage.checkIfAddUpdateDocumentOwnerPermissionIsDisabled()
await attachScreenshot('TESTS-342_QARA_roles.png', page)
await settingsPage.clickDefaultDocuments()
await settingsPage.chooseRole('Qualified User')
await settingsPage.checkPermissionsExistQualifyUser()
await settingsPage.checkIfAddUpdateDocumentOwnerPermissionIsDisabled()
await attachScreenshot('TESTS-342_User_roles.png', page)
})
})
})

View File

@ -1,5 +1,13 @@
import { test } from '@playwright/test'
import { attachScreenshot, generateId, HomepageURI, PlatformSettingSecond, PlatformURI } from '../utils'
import {
attachScreenshot,
DocumentURI,
generateId,
getSecondPage,
HomepageURI,
PlatformSettingSecond,
PlatformURI
} from '../utils'
import { allure } from 'allure-playwright'
import { SettingsPage } from './../model/setting-page'
@ -152,4 +160,29 @@ test.describe('ISO 13485, 4.2.4 Control of documents ensure that documents of ex
})
await attachScreenshot('TESTS-405_status_is_deleted.png', page)
})
test('TESTS-390. As a workspace admin, I can assign a user to any private space (e.g. Task, Controlled doc, Product, Training)', async ({
page,
browser
}) => {
await allure.description(
'Requirement\nUser is not a part of space members and cannot see or edit any document from that space'
)
await allure.tms('TESTS-390', 'https://tracex.hc.engineering/workbench/platform/tracker/TESTS-390')
const folderName = faker.word.words(1)
const userSecondPage = await getSecondPage(browser)
const documentContentPage = new DocumentContentPage(page)
const documentContentPageSecond = new DocumentContentPage(userSecondPage)
await (await userSecondPage.goto(`${PlatformURI}/${DocumentURI}`))?.finished()
await test.step('2. create a new space', async () => {
await documentContentPage.clickDocumentsSpace()
await documentContentPage.clickOnTeamspaceOrArrow()
await documentContentPage.fillDocumentAndSetMemberPrivate(folderName)
await test.step('2. check if user can see space', async () => {
await documentContentPageSecond.clickDocumentsSpace()
await documentContentPageSecond.checkIfTheSpaceIsVisible(folderName, true)
await attachScreenshot('TESTS-391_space_not_existing.png', userSecondPage)
})
})
})
})

View File

@ -84,6 +84,21 @@ export class DocumentContentPage extends DocumentCommonPage {
readonly createNewTemplateFromSpace: Locator
readonly okButton: Locator
readonly documentThreeDots: Locator
readonly buttonSubmitReview: Locator
readonly completeReviewButton: Locator
readonly approveButton: Locator
readonly documentsSpace: Locator
readonly contacts: Locator
readonly createTeamspace: Locator
readonly employee: Locator
readonly employeeDropdown: Locator
readonly kickEmployee: Locator
readonly confirmKickEmployee: Locator
readonly openTeam: Locator
readonly privateToggle: Locator
readonly inputTeamspaceName: Locator
readonly teamspaceArrow: Locator
readonly infoModal: Locator
constructor (page: Page) {
super(page)
@ -141,7 +156,7 @@ export class DocumentContentPage extends DocumentCommonPage {
this.roleSelector = page.getByRole('button', { name: 'Members' })
this.selectRoleMemberAJ = page.getByRole('button', { name: 'AJ Appleseed John' })
this.selectRoleMemberDK = page.getByRole('button', { name: 'DK Dirak Kainin' })
this.createButton = page.getByRole('button', { name: 'Create' })
this.createButton = page.getByRole('button', { name: 'Create', exact: true })
this.createNewDocument = page.getByRole('button', { name: 'Create new document' })
this.selectCustom = page.getByText('Custom')
this.customSpecificReason = page.getByPlaceholder('Specify the reason...')
@ -178,12 +193,85 @@ export class DocumentContentPage extends DocumentCommonPage {
this.createNewTemplateFromSpace = page.getByRole('button', { name: 'Create new template' })
this.okButton = page.getByRole('button', { name: 'Ok', exact: true })
this.documentThreeDots = page.locator("div[class='no-print ml-1'] button[type='button']")
this.buttonSubmitReview = page.getByRole('button', { name: 'Submit' })
this.completeReviewButton = page.getByRole('button', { name: 'Complete review' })
this.approveButton = page.getByRole('button', { name: 'Approve' })
this.documentsSpace = page.locator('[id="app-document\\:string\\:DocumentApplication"]')
this.contacts = page.locator('[id="app-contact\\:string\\:Contacts"]')
this.createTeamspace = page.getByRole('button', { name: 'Create teamspace' })
this.employee = page.getByRole('button', { name: 'Employee' })
this.employeeDropdown = page.locator('div:nth-child(4) > button').first()
this.kickEmployee = page.getByRole('button', { name: 'Kick employee' })
this.confirmKickEmployee = page.getByRole('button', { name: 'Ok' })
this.openTeam = page.getByText('Team')
this.privateToggle = page.locator('#teamspace-private span')
this.inputTeamspaceName = page.getByPlaceholder('New teamspace')
this.teamspaceArrow = page.locator('.w-full > button:nth-child(2)')
this.infoModal = page.locator('#btnGID-info')
}
async checkDocumentTitle (title: string): Promise<void> {
await expect(this.buttonDocumentTitle).toContainText(title)
}
async clickDocumentsSpace (): Promise<void> {
await this.documentsSpace.click()
}
async clickCreateTeamspace (): Promise<void> {
await this.createTeamspace.click()
}
async clickContacts (): Promise<void> {
await this.contacts.click()
}
async clickEmployee (): Promise<void> {
await this.employee.click()
}
async selectEmployee (employee: string): Promise<void> {
await this.page.getByRole('link', { name: employee }).click()
}
async clickEmployeeDropdown (): Promise<void> {
await this.employeeDropdown.click()
}
async clickKickEmployee (): Promise<void> {
await this.kickEmployee.click()
}
async clickConfirmKickEmployee (): Promise<void> {
await this.confirmKickEmployee.click()
}
async checkIfEmployeeIsKicked (employee: string): Promise<void> {
await this.page.getByRole('link', { name: 'Employee' }).getByRole('button').first().click()
await expect(this.page.getByText(employee + ' Inactive')).toBeVisible()
}
async checkIfUserCanKick (): Promise<void> {
await expect(this.kickEmployee).not.toBeVisible()
}
async clickOpenTeam (): Promise<void> {
await this.openTeam.click()
}
async checkIfReviewersAndApproversAreVisible (): Promise<void> {
await expect(this.page.getByText('Appleseed John').first()).toBeVisible()
await expect(this.page.getByText('Dirak Kainin')).toBeVisible()
await expect(this.page.getByText('Appleseed John').nth(1)).toBeVisible()
}
async checkTheUserCantChangeReviewersAndApprovers (): Promise<void> {
await this.page.getByText('Appleseed John').first().click()
await expect(this.page.getByText('Dirak Kainin').nth(1)).not.toBeVisible()
await this.page.getByText('Dirak Kainin').click()
await expect(this.page.getByText('Dirak Kainin').nth(1)).not.toBeVisible()
}
async clickDocumentHeader (name: string): Promise<void> {
await this.page.getByRole('button', { name }).click()
}
@ -257,6 +345,16 @@ export class DocumentContentPage extends DocumentCommonPage {
await this.createButton.click()
}
async clickApproveButtonAndFillPassword (): Promise<void> {
await this.approveButton.click()
await this.inputPassword.fill(PlatformPassword)
await this.buttonSubmit.click()
}
async clickApproveButton (): Promise<void> {
await this.approveButton.click()
}
async expectCategoryCreated (categoryTitle: string, categoryCode: string): Promise<void> {
await expect(this.page.getByText(categoryTitle)).toBeVisible()
await expect(this.page.getByRole('link', { name: categoryCode })).toBeVisible()
@ -287,6 +385,29 @@ export class DocumentContentPage extends DocumentCommonPage {
}
}
async addReviewersFromTeam (anotherReviewer: boolean = false): Promise<void> {
await this.page.waitForTimeout(500)
await this.page.getByText('Team').click()
await this.page.getByText('Add member').nth(1).click()
if (anotherReviewer) {
await this.page.getByRole('button', { name: 'DK Dirak Kainin' }).click()
}
await this.selectRoleMemberAJ.click()
await this.page.keyboard.press('Escape')
}
async addApproversFromTeam (): Promise<void> {
await this.page.waitForTimeout(500)
await this.page.getByText('Add member').nth(2).click()
await this.page.getByRole('button', { name: 'DK Dirak Kainin' }).click()
await this.page.keyboard.press('Escape')
}
async sendForReview (): Promise<void> {
await this.buttonSendForReview.click()
await this.buttonSubmitReview.click()
}
async addContent (content: string, append: boolean = false, newParagraph: boolean = false): Promise<void> {
if (newParagraph) {
await this.contentLocator.press('Enter')
@ -357,6 +478,44 @@ export class DocumentContentPage extends DocumentCommonPage {
await this.createButton.click()
}
async fillDocumentAndSetMember (spaceName: string): Promise<void> {
await this.inputSpaceName.fill(spaceName)
await this.page.getByRole('button', { name: 'AJ Appleseed John' }).first().click()
await this.page.getByRole('button', { name: 'AQ Admin Qara' }).click()
await this.page.getByRole('button', { name: 'AJ Appleseed John' }).nth(1).click()
await this.page.keyboard.press('Escape')
await this.page.getByRole('button', { name: 'Create' }).click()
}
async checkIfUserCanCreateDocument (spaceName: string): Promise<void> {
await this.page.getByRole('button', { name: 'New document', exact: true }).click()
await this.page.locator('[id="space\\.selector"]').click()
await expect(this.page.locator('.selectPopup').getByRole('button', { name: spaceName })).not.toBeVisible()
}
async fillDocumentAndSetMemberPrivate (spaceName: string): Promise<void> {
await this.inputTeamspaceName.fill(spaceName)
await this.privateToggle.click()
await this.page.getByRole('button', { name: 'DK Dirak Kainin' }).nth(1).click()
await this.page.getByRole('button', { name: 'AJ Appleseed John' }).click()
await this.page.keyboard.press('Escape')
await this.page.getByRole('button', { name: 'Create', exact: true }).click()
}
async clickTeamspaceArrow (): Promise<void> {
await this.teamspaceArrow.click()
}
async clickOnTeamspaceOrArrow (): Promise<void> {
const teamspaceOrArrow = await this.page.isVisible('.w-full > button:nth-child(2)')
if (teamspaceOrArrow) {
await this.clickTeamspaceArrow()
await this.createTeamspace.click()
} else {
await this.createTeamspace.click()
}
}
async fillQuaraManager (spaceName: string): Promise<void> {
await this.inputSpaceName.fill(spaceName)
await this.roleSelector.nth(2).click()
@ -375,6 +534,31 @@ export class DocumentContentPage extends DocumentCommonPage {
await this.createButton.click()
}
async fillTeamspaceFormManager (spaceName: string): Promise<void> {
await this.page.getByPlaceholder('New teamspace').fill(spaceName)
// await this.page.getByRole('button', { name: 'DK Dirak Kainin' }).first().click()
// await this.page.getByRole('button', { name: 'DK Dirak Kainin' }).nth(2).click()
// await this.page.keyboard.press('Escape')
await this.page.waitForTimeout(1000)
await this.createButton.click()
}
async changeTeamspaceMembers (spaceName: string): Promise<void> {
await this.page.getByRole('button', { name: spaceName }).hover()
await this.page.getByRole('button', { name: spaceName }).getByRole('button').nth(1).click()
await this.page.getByRole('button', { name: 'Edit teamspace' }).click()
await this.page.getByRole('button', { name: 'DK Dirak Kainin' }).first().click()
await this.page.getByRole('button', { name: 'DK Dirak Kainin' }).nth(2).click()
await this.page.getByRole('button', { name: 'AJ Appleseed John' }).click()
await this.page.keyboard.press('Escape')
await this.page.waitForTimeout(1000)
await this.page.getByRole('button', { name: 'AJ DK 2 members' }).click()
await this.page.getByRole('button', { name: 'DK Dirak Kainin' }).click()
await this.page.keyboard.press('Escape')
await this.page.waitForTimeout(1000)
await this.page.getByRole('button', { name: 'Save' }).click()
}
async changeDocumentSpaceMembers (spaceName: string): Promise<void> {
await this.page.getByRole('button', { name: spaceName }).hover()
await this.page.getByRole('button', { name: spaceName }).getByRole('button').click()
@ -496,6 +680,13 @@ export class DocumentContentPage extends DocumentCommonPage {
await expect(this.textDocumentStatus).toHaveText(status)
}
async checkIfLeftModalIsOpen (): Promise<void> {
const teamspaceOrArrow = await this.page.isHidden('div.flex:has(div.label:text("Template name")) div.field')
if (teamspaceOrArrow) {
await this.infoModal.click()
}
}
async checkDocument (data: DocumentDetails): Promise<void> {
if (data.type != null && data.type !== 'N/A') {
await expect(this.textType).toHaveText(data.type)

View File

@ -5,12 +5,14 @@ export class PdfPages {
readonly printToPdf: Locator
readonly printToPdfHeader: Locator
readonly downloadPdf: Locator
readonly showFullScreenPdf: Locator
constructor (page: Page) {
this.page = page
this.printToPdf = page.getByRole('button', { name: 'Print to PDF' })
this.printToPdfHeader = page.getByText('PDF PDF print preview')
this.downloadPdf = page.locator('form').getByRole('link').getByRole('button')
this.showFullScreenPdf = page.locator('form').getByRole('button').nth(2)
}
async printToPdfClick (): Promise<void> {
@ -18,6 +20,10 @@ export class PdfPages {
await expect(this.printToPdfHeader).toBeVisible()
}
async showFullScreenPdfClick (): Promise<void> {
await this.showFullScreenPdf.click()
}
async downloadAndVerifyPdf (): Promise<void> {
const [download] = await Promise.all([this.page.waitForEvent('download'), this.downloadPdf.click()])
const filePath = await download.path()

View File

@ -8,7 +8,8 @@ export class LoginPage {
readonly buttonLogin: Locator
readonly buttonSignUp: Locator
readonly loginWithPassword: Locator
readonly invalidPasswordMessage: Locator
readonly accountNotFoundMessage: Locator
constructor (page: Page) {
this.page = page
this.inputEmail = page.locator('input[name=email]')
@ -16,6 +17,8 @@ export class LoginPage {
this.buttonLogin = page.locator('button', { hasText: 'Log In' })
this.buttonSignUp = page.locator('a.title', { hasText: 'Sign Up' })
this.loginWithPassword = page.locator('a', { hasText: 'Login with password' })
this.invalidPasswordMessage = page.getByText('Invalid password')
this.accountNotFoundMessage = page.getByText('Account not found')
}
async goto (): Promise<void> {
@ -29,6 +32,19 @@ export class LoginPage {
await this.buttonLogin.click()
}
async checkIfErrorMessageIsShown (message: string): Promise<void> {
if (message === 'Invalid password') {
await expect(this.invalidPasswordMessage).toContainText(message)
}
if (message === 'Account not found') {
await expect(this.accountNotFoundMessage).toContainText(message)
}
}
async clickOnLoginWithPassword (): Promise<void> {
await this.loginWithPassword.click()
}
async checkIfUserIsLoggedIn (credentials: string): Promise<void> {
if (credentials === 'wrong-password') {
await expect(this.buttonLogin).toBeVisible()

View File

@ -18,6 +18,7 @@ export class SettingsPage {
readonly deleteDocumentCategoryPermission: Locator
readonly updateSpacePermission: Locator
readonly addRoleUpdatePermissionOwner: Locator
readonly addUpdateDocumentOwnerPermission: Locator
constructor (page: Page) {
this.page = page
@ -37,6 +38,7 @@ export class SettingsPage {
this.deleteDocumentCategoryPermission = page.getByText('Delete document category', { exact: true })
this.updateSpacePermission = page.getByText('Update space', { exact: true })
this.addRoleUpdatePermissionOwner = page.getByRole('button', { name: 'Update document owner' })
this.addUpdateDocumentOwnerPermission = page.locator('.hulyTableAttr-header > .font-medium-14')
}
async openProfileMenu (): Promise<void> {
@ -69,6 +71,10 @@ export class SettingsPage {
await expect(this.updateSpacePermission).toBeVisible()
}
async checkIfAddUpdateDocumentOwnerPermissionIsDisabled (): Promise<void> {
await expect(this.addUpdateDocumentOwnerPermission).toBeDisabled()
}
async checkPermissionsExistQualifyUser (): Promise<void> {
await expect(this.reviewDocumentPermission).toBeVisible()
await expect(this.approveDocumentPermission).toBeVisible()

View File

@ -0,0 +1,51 @@
import { expect, Page } from '@playwright/test'
import { join } from 'path'
export class VisualCheck {
readonly page: Page
constructor (page: Page) {
this.page = page
}
async compareScreenshot (selector: string | null, screenshotName: string): Promise<void> {
let screenshot
if (selector !== null && selector !== undefined) {
const element = this.page.locator(selector)
await expect(element).toBeVisible()
screenshot = await element.screenshot()
} else {
screenshot = await this.page.screenshot()
}
// Compare the screenshot with the stored snapshot
expect(screenshot).toMatchSnapshot(join(__dirname, '..', 'screenshots', `${screenshotName}.png`), {
maxDiffPixelRatio: 0.2
})
}
async comparePDFPreview (screenshotName: string): Promise<void> {
// Wait for the iframe to be present in the DOM
const iframe = this.page.locator('iframe.pdfviewer-content')
await iframe.waitFor({ state: 'attached', timeout: 10000 })
// Wait for the iframe to finish loading
await this.page.waitForFunction(
() => {
const iframe = document.querySelector('iframe.pdfviewer-content') as HTMLIFrameElement
return iframe?.contentDocument?.readyState === 'complete'
},
{ timeout: 30000 }
)
const pdfPreviewModal = this.page.locator('.antiDialog > .content')
await expect(pdfPreviewModal).toBeVisible()
const screenshot = await this.page.screenshot()
expect(screenshot).toMatchSnapshot(join(__dirname, '..', 'screenshots', `${screenshotName}.png`), {
maxDiffPixelRatio: 0.2
})
}
}

View File

@ -74,3 +74,7 @@ export async function * iterateLocator (locator: Locator): AsyncGenerator<Locato
yield locator.nth(index)
}
}
export async function waitForNetworIdle (page: Page, timeout = 2000): Promise<void> {
await Promise.race([page.waitForLoadState('networkidle'), new Promise((resolve) => setTimeout(resolve, timeout))])
}