mirror of
https://github.com/hcengineering/platform.git
synced 2025-05-30 20:28:20 +00:00
Visual check for PDF (#6599)
Signed-off-by: Jasmin <jasmin@hardcoreeng.com>
This commit is contained in:
parent
5061856f12
commit
1d3299e384
@ -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
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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/",
|
||||
|
38
qms-tests/sanity/storageFourth-dev.json
Normal file
38
qms-tests/sanity/storageFourth-dev.json
Normal 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"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
38
qms-tests/sanity/storageFourth.json
Normal file
38
qms-tests/sanity/storageFourth.json
Normal 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"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
101
qms-tests/sanity/tests/documents/ES-20.spec.ts
Normal file
101
qms-tests/sanity/tests/documents/ES-20.spec.ts
Normal 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)
|
||||
})
|
||||
})
|
Binary file not shown.
After Width: | Height: | Size: 41 KiB |
29
qms-tests/sanity/tests/documents/ES-40.1.spec.ts
Normal file
29
qms-tests/sanity/tests/documents/ES-40.1.spec.ts
Normal 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()
|
||||
})
|
||||
})
|
||||
})
|
35
qms-tests/sanity/tests/documents/ES-40.2.spec.ts
Normal file
35
qms-tests/sanity/tests/documents/ES-40.2.spec.ts
Normal 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')
|
||||
})
|
||||
})
|
54
qms-tests/sanity/tests/documents/ES-40.spec.ts
Normal file
54
qms-tests/sanity/tests/documents/ES-40.spec.ts
Normal 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')
|
||||
})
|
||||
})
|
||||
})
|
289
qms-tests/sanity/tests/documents/ES-50.spec.ts
Normal file
289
qms-tests/sanity/tests/documents/ES-50.spec.ts
Normal 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)
|
||||
})
|
||||
})
|
Binary file not shown.
After Width: | Height: | Size: 43 KiB |
Binary file not shown.
After Width: | Height: | Size: 42 KiB |
@ -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)
|
||||
})
|
||||
})
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 41 KiB |
Binary file not shown.
After Width: | Height: | Size: 42 KiB |
Binary file not shown.
After Width: | Height: | Size: 32 KiB |
@ -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)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -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)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -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)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -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)
|
||||
|
@ -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()
|
||||
|
@ -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()
|
||||
|
@ -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()
|
||||
|
51
qms-tests/sanity/tests/model/visual-check.ts
Normal file
51
qms-tests/sanity/tests/model/visual-check.ts
Normal 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
|
||||
})
|
||||
}
|
||||
}
|
@ -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))])
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user