Add livness check for login and workspace (#5532)

Signed-off-by: Jasmin <jasmin@hardcoreeng.com>
This commit is contained in:
JasminMus 2024-05-08 19:35:24 +02:00 committed by GitHub
parent 2c3ffba681
commit d1e0790d08
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 199 additions and 17 deletions

View File

@ -4,4 +4,4 @@ PLATFORM_USER='user1'
PLATFORM_USER_SECOND='user2'
PLATFORM_TOKEN='eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJlbWFpbCI6InVzZXIxIiwid29ya3NwYWNlIjoic2FuaXR5LXdzIn0.hfUCqePHO-WNps2by4B-CYGKIpDpLG0WVCUUtU-SVI4'
SETTING=storage.json
SETTING_SECOND=storageSecond.json
SETTING_SECOND=storageSecond.json

View File

@ -1,19 +1,52 @@
import { test } from '@playwright/test'
import { PlatformUser } from './utils'
import { PlatformUser, checkIfUrlContains } from './utils'
import { LoginPage } from './model/login-page'
import { SelectWorkspacePage } from './model/select-workspace-page'
import { CommonTrackerPage } from './model/tracker/common-tracker-page'
import { TrackerNavigationMenuPage } from './model/tracker/tracker-navigation-menu-page'
import { SignUpPage } from './model/signup-page'
test.describe('login test', () => {
test('check login', async ({ page }) => {
page.on('pageerror', (exception) => {
console.log('Uncaught exception:')
console.log(exception.message)
})
const loginPage = new LoginPage(page)
await loginPage.goto()
await loginPage.login(PlatformUser, '1234')
let loginPage: LoginPage
let commonTrackerPage: CommonTrackerPage
let signupPage: SignUpPage
let trackerNavigationMenuPage: TrackerNavigationMenuPage
let selectWorkspacePage: SelectWorkspacePage
const selectWorkspacePage = new SelectWorkspacePage(page)
test.beforeEach(async ({ page }) => {
loginPage = new LoginPage(page)
commonTrackerPage = new CommonTrackerPage(page)
signupPage = new SignUpPage(page)
trackerNavigationMenuPage = new TrackerNavigationMenuPage(page)
selectWorkspacePage = new SelectWorkspacePage(page)
await loginPage.goto()
})
test('check login', async () => {
await loginPage.login(PlatformUser, '1234')
await selectWorkspacePage.selectWorkspace('SanityTest')
await commonTrackerPage.checkIfMainPanelIsVisible()
await trackerNavigationMenuPage.checkIfTrackerSidebarIsVisible()
})
test('check login with wrong user and if the button is disabled ', async ({ page }) => {
await loginPage.checkIfLoginButtonIsDissaabled()
await loginPage.login(PlatformUser, 'wrong-password')
await loginPage.checkIfErrorMessageIsShown()
})
test('check if user is able to go to to recovery, then login and then signup', async ({ page }) => {
await checkIfUrlContains(page, '/login')
await loginPage.checkIfLoginButtonIsDissaabled()
await loginPage.clickOnRecover()
await checkIfUrlContains(page, '/password')
await loginPage.checkIfPasswordRecoveryIsVisible()
await loginPage.clickOnRecoveryLogin()
await checkIfUrlContains(page, '/login')
await loginPage.checkIfLoginButtonIsDissaabled()
await loginPage.clickOnRecover()
await loginPage.clickOnRecoverySignUp()
await signupPage.checkIfSignUpButtonIsDisabled()
await checkIfUrlContains(page, '/signup')
})
})

View File

@ -12,7 +12,15 @@ export class LoginPage {
inputPassword = (): Locator => this.page.locator('input[name=current-password]')
buttonLogin = (): Locator => this.page.locator('button', { hasText: 'Log In' })
linkSignUp = (): Locator => this.page.locator('a.title', { hasText: 'Sign Up' })
invalidPasswordMessage = (): Locator => this.page.getByText('Invalid password')
recoverLink = (): Locator => this.page.getByRole('link', { name: 'Recover' })
passwordRecovery = (): Locator => this.page.getByText('Password recovery')
recoveryLoginText = (): Locator => this.page.getByText('Know your password? Log In')
recoverySignUpText = (): Locator => this.page.getByText('Do not have an account? Sign Up')
recoveryLogin = (): Locator => this.page.getByRole('link', { name: 'Log In' })
recoverySignUp = (): Locator => this.page.getByRole('link', { name: 'Sign Up' })
// ACTIONS
async goto (): Promise<void> {
await (await this.page.goto(`${PlatformURI}/login/login`))?.finished()
}
@ -21,10 +29,38 @@ export class LoginPage {
await this.linkSignUp().click()
}
async clickOnRecover (): Promise<void> {
await this.recoverLink().click()
}
async clickOnRecoveryLogin (): Promise<void> {
await this.recoveryLogin().click()
}
async clickOnRecoverySignUp (): Promise<void> {
await this.recoverySignUp().click()
}
async login (email: string, password: string): Promise<void> {
await this.inputEmail().fill(email)
await this.inputPassword().fill(password)
expect(await this.buttonLogin().isEnabled()).toBe(true)
await this.buttonLogin().click()
}
// ASSERTS
async checkIfErrorMessageIsShown (): Promise<void> {
await expect(this.invalidPasswordMessage()).toContainText('Invalid password')
}
async checkIfLoginButtonIsDissaabled (): Promise<void> {
await expect(this.buttonLogin()).toBeDisabled()
}
async checkIfPasswordRecoveryIsVisible (): Promise<void> {
await expect(this.passwordRecovery()).toBeVisible()
await expect(this.recoveryLoginText()).toBeVisible()
await expect(this.recoverySignUpText()).toBeVisible()
}
}

View File

@ -11,6 +11,10 @@ export class UserProfilePage {
applyChangesButton = (): Locator => this.page.locator('.editor-container button:nth-child(3)')
addSocialLinksButton = (): Locator => this.page.locator('[id="presentation:string:AddSocialLinks"]')
selectProfile = (name: string): Locator => this.page.locator(`text=${name}`)
leaveWorkspaceButton = (): Locator => this.page.getByRole('button', { name: 'Leave workspace' })
leaveWorkspaceCancelButton = (): Locator => this.page.getByRole('button', { name: 'Cancel' })
leaveWorkspaceConfirmButton = (): Locator => this.page.getByRole('button', { name: 'Ok' })
accountDissabledMessage = (): Locator => this.page.getByRole('heading')
constructor (page: Page) {
this.page = page
@ -28,8 +32,21 @@ export class UserProfilePage {
await this.profileButton().click()
}
async clickLeaveWorkspaceButton (): Promise<void> {
await this.leaveWorkspaceButton().click()
}
async clickLeaveWorkspaceConfirmButton (): Promise<void> {
await this.leaveWorkspaceConfirmButton().click()
}
async clickLeaveWorkspaceCancelButton (): Promise<void> {
await this.leaveWorkspaceCancelButton().click()
}
async selectProfileByName (name: string): Promise<void> {
await this.selectProfile(name).click()
await this.page.waitForTimeout(1000)
}
async verifyProfilePageUrl (expectedUrl: string): Promise<void> {
@ -54,4 +71,8 @@ export class UserProfilePage {
async applyChanges (): Promise<void> {
await this.applyChangesButton().click()
}
async checkIfAccountIsDisabled (): Promise<void> {
await expect(this.accountDissabledMessage()).toContainText('Account is disabled')
}
}

View File

@ -13,8 +13,8 @@ export class SelectWorkspacePage extends CommonPage {
buttonCreateWorkspace = (): Locator => this.page.locator('button > span', { hasText: 'Create workspace' })
buttonWorkspaceName = (): Locator => this.page.locator('input')
buttonCreateNewWorkspace = (): Locator => this.page.locator('div.form-row button')
workspaceButtonByName = (workspace: string): Locator => this.buttonWorkspace().filter({ hasText: workspace })
createAnotherWorkspace = (): Locator => this.page.getByRole('link', { name: 'Create workspace' })
async selectWorkspace (workspace: string): Promise<void> {
await this.workspaceButtonByName(workspace).click()
@ -24,10 +24,17 @@ export class SelectWorkspacePage extends CommonPage {
await this.buttonWorkspaceName().fill(workspaceName)
}
async createWorkspace (workspaceName: string): Promise<void> {
await this.buttonCreateWorkspace().waitFor({ state: 'visible' })
await this.enterWorkspaceName(workspaceName)
expect(await this.buttonCreateNewWorkspace().isEnabled()).toBe(true)
await this.buttonCreateNewWorkspace().click()
async createWorkspace (workspaceName: string, worskpaceNew: boolean = true): Promise<void> {
if (worskpaceNew) {
await this.buttonCreateWorkspace().waitFor({ state: 'visible' })
await this.enterWorkspaceName(workspaceName)
expect(await this.buttonCreateNewWorkspace().isEnabled()).toBe(true)
await this.buttonCreateNewWorkspace().click()
} else {
await this.createAnotherWorkspace().click()
await this.enterWorkspaceName(workspaceName)
expect(await this.buttonCreateNewWorkspace().isEnabled()).toBe(true)
await this.buttonCreateNewWorkspace().click()
}
}
}

View File

@ -58,4 +58,8 @@ export class SignUpPage extends CommonPage {
await this.buttonSignUp().click()
}
}
async checkIfSignUpButtonIsDisabled (): Promise<void> {
await expect(this.buttonSignUp()).toBeDisabled()
}
}

View File

@ -93,6 +93,15 @@ export class CommonTrackerPage extends CalendarPage {
viewButton = (): Locator => this.page.locator('button:has-text("View")')
firstOptionButton = (): Locator => this.page.locator('.antiCard >> button >> nth=0')
assigneeMenuItem = (): Locator => this.page.locator('.menu-item:has-text("Assignee")')
header = (): Locator => this.page.getByText('Issues All Active Backlog')
filter = (): Locator => this.page.getByRole('button', { name: 'Filter' })
view = (): Locator => this.page.getByRole('button', { name: 'View' })
showMore = (): Locator => this.page.getByRole('button', { name: 'Show' })
task1 = (): Locator => this.page.getByRole('link', { name: 'Welcome to Huly! 🌟' })
task2 = (): Locator => this.page.getByRole('link', { name: 'Create your first Project 📌' })
task3 = (): Locator => this.page.getByRole('link', { name: 'Create your first Issue 📝' })
task4 = (): Locator => this.page.getByRole('link', { name: 'Schedule your first Todo 📆' })
task5 = (): Locator => this.page.getByRole('link', { name: 'Explore all Huly has to offer' })
// Actions
async selectPanelAndViewlet (panel: string, viewletSelector: string): Promise<void> {
@ -282,4 +291,19 @@ export class CommonTrackerPage extends CalendarPage {
await this.buttonMoreActions().click()
await this.checkDropdownHasNo(this.page, action)
}
async checkIfMainPanelIsVisible (): Promise<void> {
await expect(this.header()).toBeVisible({ timeout: 60000 })
await expect(this.filter()).toBeVisible()
await expect(this.view()).toBeVisible()
await expect(this.showMore()).toBeVisible()
}
async checkIfTasksAreVisable (): Promise<void> {
await expect(this.task1()).toBeVisible()
await expect(this.task2()).toBeVisible()
await expect(this.task3()).toBeVisible()
await expect(this.task4()).toBeVisible()
await expect(this.task5()).toBeVisible()
}
}

View File

@ -30,6 +30,15 @@ export class TrackerNavigationMenuPage extends CommonPage {
hasText: 'Components'
})
newIssue = (): Locator => this.page.locator('button', { hasText: 'New issue' })
myIssues = (): Locator => this.page.getByRole('link', { name: 'My issues', exact: true })
allIssues = (): Locator => this.page.getByRole('link', { name: 'All issues', exact: true })
allProjects = (): Locator => this.page.getByRole('link', { name: 'All projects' })
issues = (): Locator => this.page.getByRole('link', { name: 'Issues', exact: true })
components = (): Locator => this.page.getByRole('link', { name: 'Components' })
milestone = (): Locator => this.page.getByRole('link', { name: 'Milestones' })
templates = (): Locator => this.page.getByRole('link', { name: 'Templates' })
createProjectButton = (): Locator => this.buttonCreateProject().locator('button.small')
async pressCreateProjectButton (): Promise<void> {
@ -74,4 +83,18 @@ export class TrackerNavigationMenuPage extends CommonPage {
async openComponentsForProject (projectName: string): Promise<void> {
await this.componentsLinkForProject(projectName).click()
}
async checkIfTrackerSidebarIsVisible (): Promise<void> {
await expect(this.newIssue()).toBeVisible()
await expect(this.myIssues()).toBeVisible()
await expect(this.allIssues()).toBeVisible()
await expect(this.allProjects()).toBeVisible()
}
async checkIfTrackerSidebarIsVisibleForLiveProject (): Promise<void> {
await expect(this.issues()).toBeVisible()
await expect(this.components()).toBeVisible()
await expect(this.milestone()).toBeVisible()
await expect(this.templates()).toBeVisible()
}
}

View File

@ -83,3 +83,11 @@ export async function attachScreenshot (name: string, page: Page): Promise<void>
})
await page.screenshot({ path: `screenshots/${name}` })
}
export async function checkIfUrlContains (page: Page, url: string): Promise<void> {
expect(page.url()).toContain(url)
}
export async function waitForNetworIdle (page: Page, timeout = 2000): Promise<void> {
await Promise.race([page.waitForLoadState('networkidle'), new Promise((resolve) => setTimeout(resolve, timeout))])
}

View File

@ -10,6 +10,8 @@ import { IssuesPage } from '../model/tracker/issues-page'
import { IssuesDetailsPage } from '../model/tracker/issues-details-page'
import { TrackerNavigationMenuPage } from '../model/tracker/tracker-navigation-menu-page'
import { SignInJoinPage } from '../model/signin-page'
import { UserProfilePage } from '../model/profile/user-profile-page'
import { faker } from '@faker-js/faker'
test.describe('Workspace tests', () => {
let loginPage: LoginPage
@ -18,6 +20,7 @@ test.describe('Workspace tests', () => {
let leftSideMenuPage: LeftSideMenuPage
let trackerNavigationMenuPage: TrackerNavigationMenuPage
let issuesPage: IssuesPage
let userProfilePage: UserProfilePage
test.beforeEach(async ({ page }) => {
loginPage = new LoginPage(page)
@ -26,6 +29,7 @@ test.describe('Workspace tests', () => {
leftSideMenuPage = new LeftSideMenuPage(page)
trackerNavigationMenuPage = new TrackerNavigationMenuPage(page)
issuesPage = new IssuesPage(page)
userProfilePage = new UserProfilePage(page)
})
test('Create a workspace with a custom name', async () => {
@ -223,4 +227,26 @@ test.describe('Workspace tests', () => {
await leftSideMenuPageSecond.clickTracker()
})
})
test('User can leave workspace', async () => {
const newUser: SignUpData = {
firstName: faker.person.firstName(),
lastName: faker.person.lastName(),
email: faker.internet.email(),
password: '1234'
}
const newWorkspaceName = `Some HULY #@$ WS - ${generateId(12)}`
await loginPage.goto()
await loginPage.clickSignUp()
await signUpPage.signUp(newUser)
await selectWorkspacePage.createWorkspace(newWorkspaceName)
await trackerNavigationMenuPage.checkIfTrackerSidebarIsVisible()
await userProfilePage.openProfileMenu()
await userProfilePage.selectProfileByName(newUser.lastName + ' ' + newUser.firstName)
await userProfilePage.clickLeaveWorkspaceButton()
await userProfilePage.clickLeaveWorkspaceCancelButton()
await userProfilePage.clickLeaveWorkspaceButton()
await userProfilePage.clickLeaveWorkspaceConfirmButton()
await userProfilePage.checkIfAccountIsDisabled()
})
})