mirror of
https://github.com/hcengineering/platform.git
synced 2024-11-22 21:50:34 +03:00
Onboarding workspace test preparation (#5708)
Signed-off-by: Jasmin <jasmin@hardcoreeng.com>
This commit is contained in:
parent
3f34143b16
commit
e818265c76
@ -10,6 +10,10 @@ export class NotificationPage {
|
||||
notificationLocator = (name: string): Locator =>
|
||||
this.page.locator('div[class*="inbox-activity"] span', { hasText: name })
|
||||
|
||||
async clickOnNotification (name: string): Promise<void> {
|
||||
await this.notificationLocator(name).click()
|
||||
}
|
||||
|
||||
async checkNotificationIssue (name: string, assignee: string): Promise<void> {
|
||||
const notification = this.notificationLocator(name)
|
||||
await expect(notification.locator('xpath=../../..').locator('a span.ap-label')).toHaveText(assignee)
|
||||
|
@ -16,6 +16,18 @@ export class UserProfilePage {
|
||||
leaveWorkspaceConfirmButton = (): Locator => this.page.getByRole('button', { name: 'Ok' })
|
||||
accountDissabledMessage = (): Locator => this.page.getByRole('heading')
|
||||
changeAccount = (): Locator => this.page.getByRole('link', { name: 'Change account' })
|
||||
settings = (): Locator => this.page.getByRole('button', { name: 'Settings' })
|
||||
accountSettings = (): Locator => this.page.getByRole('button', { name: 'Account settings' })
|
||||
userAvatarMenu = (): Locator => this.page.locator('.mr-8 > .cursor-pointer')
|
||||
savaAvatarButton = (): Locator => this.page.getByRole('button', { name: 'Save' }).nth(1)
|
||||
selectWorkspace = (): Locator => this.page.getByRole('button', { name: 'Select workspace' })
|
||||
changePasswordButton = (): Locator => this.page.getByRole('button', { name: 'Change password' })
|
||||
currentPassword = (): Locator => this.page.getByPlaceholder('Enter current password')
|
||||
newPassword = (): Locator => this.page.getByPlaceholder('Enter new password')
|
||||
repeatPassword = (): Locator => this.page.getByPlaceholder('Repeat new password')
|
||||
savePassword = (): Locator => this.page.getByRole('button', { name: 'Save' })
|
||||
savedButton = (): Locator => this.page.getByRole('button', { name: 'Saved' })
|
||||
signOutButton = (): Locator => this.page.getByRole('button', { name: 'Sign out' })
|
||||
|
||||
constructor (page: Page) {
|
||||
this.page = page
|
||||
@ -33,6 +45,26 @@ export class UserProfilePage {
|
||||
await this.profileButton().click()
|
||||
}
|
||||
|
||||
async clickSelectWorkspace (): Promise<void> {
|
||||
await this.selectWorkspace().click()
|
||||
}
|
||||
|
||||
async clickSettings (): Promise<void> {
|
||||
await this.settings().click()
|
||||
}
|
||||
|
||||
async clickAccountSettings (): Promise<void> {
|
||||
await this.accountSettings().click()
|
||||
}
|
||||
|
||||
async openUserAvatarMenu (): Promise<void> {
|
||||
await this.userAvatarMenu().click()
|
||||
}
|
||||
|
||||
async clickSavaAvatarButton (): Promise<void> {
|
||||
await this.savaAvatarButton().click()
|
||||
}
|
||||
|
||||
async clickChangeAccount (): Promise<void> {
|
||||
await this.changeAccount().click()
|
||||
}
|
||||
@ -63,6 +95,21 @@ export class UserProfilePage {
|
||||
await this.locationInput().fill(newLocation)
|
||||
}
|
||||
|
||||
async changePassword (currentPassword: string, newPassword: string): Promise<void> {
|
||||
await this.changePasswordButton().click()
|
||||
await this.currentPassword().fill(currentPassword)
|
||||
await expect(this.savePassword()).toBeDisabled()
|
||||
await this.newPassword().fill(newPassword)
|
||||
await expect(this.savePassword()).toBeDisabled()
|
||||
await this.repeatPassword().fill(newPassword)
|
||||
await this.savePassword().click()
|
||||
await expect(this.savedButton()).toBeDisabled()
|
||||
}
|
||||
|
||||
async clickOnSignOutButton (): Promise<void> {
|
||||
await this.signOutButton().click()
|
||||
}
|
||||
|
||||
async addOrEditPhone (): Promise<void> {
|
||||
if ((await this.phoneContactInput().count()) === 0) {
|
||||
await this.addSocialLinksButton().click()
|
||||
|
@ -15,7 +15,8 @@ export class SelectWorkspacePage extends CommonPage {
|
||||
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' })
|
||||
|
||||
workspaceLogo = (): Locator => this.page.getByText('N', { exact: true })
|
||||
workspaceList = (workspaceName: string): Locator => this.page.getByRole('button', { name: workspaceName })
|
||||
async selectWorkspace (workspace: string): Promise<void> {
|
||||
await this.workspaceButtonByName(workspace).click()
|
||||
}
|
||||
@ -24,6 +25,10 @@ export class SelectWorkspacePage extends CommonPage {
|
||||
await this.buttonWorkspaceName().fill(workspaceName)
|
||||
}
|
||||
|
||||
async clickCreateWorkspaceLogo (): Promise<void> {
|
||||
await this.workspaceLogo().click()
|
||||
}
|
||||
|
||||
async createWorkspace (workspaceName: string, worskpaceNew: boolean = true): Promise<void> {
|
||||
if (worskpaceNew) {
|
||||
await this.buttonCreateWorkspace().waitFor({ state: 'visible' })
|
||||
@ -37,4 +42,8 @@ export class SelectWorkspacePage extends CommonPage {
|
||||
await this.buttonCreateNewWorkspace().click()
|
||||
}
|
||||
}
|
||||
|
||||
async checkIfWorkspaceExists (workspace: string): Promise<void> {
|
||||
await expect(this.workspaceList(workspace)).toBeVisible()
|
||||
}
|
||||
}
|
||||
|
59
tests/sanity/tests/model/workspace/classes-pages.ts
Normal file
59
tests/sanity/tests/model/workspace/classes-pages.ts
Normal file
@ -0,0 +1,59 @@
|
||||
import { expect, type Locator, type Page } from '@playwright/test'
|
||||
|
||||
export class ClassesPage {
|
||||
readonly page: Page
|
||||
|
||||
constructor (page: Page) {
|
||||
this.page = page
|
||||
}
|
||||
|
||||
member = (): Locator => this.page.getByRole('button', { name: 'Member' })
|
||||
contact = (): Locator => this.page.getByRole('button', { name: 'Contact' })
|
||||
person = (): Locator => this.page.getByRole('button', { name: 'Person' })
|
||||
employee = (): Locator => this.page.getByRole('button', { name: 'Employee' })
|
||||
worker = (): Locator => this.page.getByRole('button', { name: 'Worker' })
|
||||
talent = (): Locator => this.page.getByRole('button', { name: 'Talent' })
|
||||
company = (): Locator => this.page.getByRole('button', { name: 'Company' })
|
||||
customer = (): Locator => this.page.getByRole('button', { name: 'Customer' })
|
||||
vacancy = (): Locator => this.page.getByRole('button', { name: 'Vacancy', exact: true })
|
||||
defaultVacancy = (): Locator => this.page.getByRole('button', { name: 'Default vacancy', exact: true })
|
||||
funnel = (): Locator => this.page.getByRole('button', { name: 'Funnel', exact: true })
|
||||
defaultFunnel = (): Locator => this.page.getByRole('button', { name: 'Default funnel' })
|
||||
project = (): Locator => this.page.getByRole('button', { name: 'Project', exact: true })
|
||||
classicProject = (): Locator => this.page.getByRole('button', { name: 'Classic project', exact: true })
|
||||
board = (): Locator => this.page.getByRole('button', { name: 'Board' })
|
||||
task = (): Locator => this.page.getByRole('button', { name: 'Task' })
|
||||
application = (): Locator => this.page.getByRole('button', { name: 'Application' })
|
||||
applicant = (): Locator => this.page.getByRole('button', { name: 'Applicant' })
|
||||
lead = (): Locator => this.page.getByRole('button', { name: 'Lead' })
|
||||
issue = (): Locator => this.page.getByRole('button', { name: 'Issue' })
|
||||
card = (): Locator => this.page.getByRole('button', { name: 'Card' })
|
||||
product = (): Locator => this.page.getByRole('button', { name: 'Product' })
|
||||
|
||||
async checkIfClassesExists (): Promise<void> {
|
||||
await expect(this.member()).toBeVisible()
|
||||
await expect(this.contact()).toBeVisible()
|
||||
await expect(this.person()).toBeVisible()
|
||||
await expect(this.employee()).toBeVisible()
|
||||
await expect(this.worker()).toBeVisible()
|
||||
await expect(this.talent()).toBeVisible()
|
||||
await expect(this.company()).toBeVisible()
|
||||
await expect(this.customer()).toBeVisible()
|
||||
await expect(this.vacancy()).toBeVisible()
|
||||
await expect(this.defaultVacancy()).toBeVisible()
|
||||
await expect(this.funnel()).toBeVisible()
|
||||
await expect(this.defaultFunnel()).toBeVisible()
|
||||
await expect(this.project()).toBeVisible()
|
||||
await expect(this.classicProject()).toBeVisible()
|
||||
await expect(this.board()).toBeVisible()
|
||||
await expect(this.task()).toBeVisible()
|
||||
await expect(this.application()).toBeVisible()
|
||||
await expect(this.applicant()).toBeVisible()
|
||||
await expect(this.lead().nth(0)).toBeVisible()
|
||||
await expect(this.lead().nth(1)).toBeVisible()
|
||||
await expect(this.issue().nth(0)).toBeVisible()
|
||||
await expect(this.issue().nth(1)).toBeVisible()
|
||||
await expect(this.card()).toBeVisible()
|
||||
await expect(this.product()).toBeVisible()
|
||||
}
|
||||
}
|
77
tests/sanity/tests/model/workspace/owner-pages.ts
Normal file
77
tests/sanity/tests/model/workspace/owner-pages.ts
Normal file
@ -0,0 +1,77 @@
|
||||
import { expect, type Locator, type Page } from '@playwright/test'
|
||||
|
||||
export class OwnersPage {
|
||||
readonly page: Page
|
||||
|
||||
constructor (page: Page) {
|
||||
this.page = page
|
||||
}
|
||||
|
||||
owner = (ownerName: string): Locator => this.page.getByRole('link', { name: ownerName })
|
||||
spacesAdminText = (): Locator => this.page.getByText('Admin Members')
|
||||
addMemberButton = (): Locator => this.page.getByRole('button', { name: 'Members' })
|
||||
selectMember = (memberName: string): Locator => this.page.getByRole('button', { name: memberName })
|
||||
workspaceLogo = (): Locator => this.page.locator('.hulyComponent > .cursor-pointer')
|
||||
publicTemplate = (): Locator => this.page.getByText('Public templates')
|
||||
createTemplate = (): Locator => this.page.getByRole('button', { name: 'CREATE TEMPLATE' })
|
||||
saveTemplate = (): Locator => this.page.getByRole('button', { name: 'Save template' })
|
||||
newTemplateName = (): Locator => this.page.getByPlaceholder('New template')
|
||||
templateName = (name: string): Locator => this.page.locator('span').filter({ hasText: name })
|
||||
createEnum = (): Locator => this.page.getByRole('button', { name: 'Create enum' })
|
||||
addEnum = (): Locator => this.page.locator('.buttons-group > button:nth-child(2)')
|
||||
enterEnumTitle = (): Locator => this.page.getByPlaceholder('Enum title')
|
||||
enterEnumName = (): Locator => this.page.getByPlaceholder('Enter option title')
|
||||
saveButton = (): Locator => this.page.getByRole('button', { name: 'Save' })
|
||||
createdEnum = (name: string): Locator => this.page.getByRole('button', { name: `${name} 1 option` })
|
||||
enum = (name: string): Locator => this.page.getByRole('button', { name })
|
||||
linkValidFor = (): Locator => this.page.getByRole('spinbutton')
|
||||
emailMask = (): Locator => this.page.getByRole('textbox', { name: 'Type text...' })
|
||||
noLimitToggleButton = (): Locator => this.page.locator('label span')
|
||||
avatarLarge = (): Locator => this.page.locator('.hulyAvatarSize-x-large.ava-image')
|
||||
|
||||
async addMember (memberName: string): Promise<void> {
|
||||
await expect(this.spacesAdminText()).toBeVisible()
|
||||
await this.addMemberButton().click()
|
||||
await this.selectMember(memberName).click()
|
||||
await this.page.keyboard.press('Escape')
|
||||
await expect(this.selectMember(memberName)).toBeVisible()
|
||||
}
|
||||
|
||||
async clickOnWorkspaceLogo (): Promise<void> {
|
||||
await this.workspaceLogo().click()
|
||||
}
|
||||
|
||||
async checkIfOwnerExists (ownerName: string): Promise<void> {
|
||||
await expect(this.owner(ownerName)).toBeVisible()
|
||||
}
|
||||
|
||||
async createTemplateWithName (templateName: string): Promise<void> {
|
||||
await expect(this.publicTemplate()).toBeVisible()
|
||||
await this.createTemplate().click()
|
||||
await this.newTemplateName().fill(templateName)
|
||||
await this.saveTemplate().click()
|
||||
await expect(this.templateName(templateName)).toBeVisible()
|
||||
}
|
||||
|
||||
async createEnumWithName (enumTitle: string, enumName: string): Promise<void> {
|
||||
await this.createEnum().click()
|
||||
await this.enterEnumTitle().fill(enumTitle)
|
||||
await this.addEnum().click()
|
||||
await this.enterEnumName().fill(enumName)
|
||||
await this.page.keyboard.press('Enter')
|
||||
await this.saveButton().click()
|
||||
await expect(this.createdEnum(enumTitle)).toBeVisible()
|
||||
await this.createdEnum(enumTitle).click()
|
||||
await expect(this.enum(enumName)).toBeVisible()
|
||||
}
|
||||
|
||||
async saveUploadedLogo (): Promise<void> {
|
||||
await this.saveButton().nth(1).click()
|
||||
await this.saveButton().click()
|
||||
}
|
||||
|
||||
async checkIfPictureIsUploaded (): Promise<void> {
|
||||
await expect(this.avatarLarge()).toBeVisible()
|
||||
await expect(this.avatarLarge()).toHaveAttribute('src')
|
||||
}
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
import { type Locator, type Page } from '@playwright/test'
|
||||
|
||||
export enum ButtonType {
|
||||
Owners,
|
||||
Spaces,
|
||||
Branding,
|
||||
TextTemplate,
|
||||
RelatedIssues,
|
||||
Classes,
|
||||
Enums,
|
||||
InviteSettings
|
||||
}
|
||||
|
||||
export class WorkspaceSettingsPage {
|
||||
readonly page: Page
|
||||
|
||||
constructor (page: Page) {
|
||||
this.page = page
|
||||
}
|
||||
|
||||
owners = (): Locator => this.page.getByRole('button', { name: 'Owners' })
|
||||
spaces = (): Locator => this.page.getByRole('button', { name: 'Spaces', exact: true })
|
||||
branding = (): Locator => this.page.getByRole('button', { name: 'Branding' })
|
||||
textTemplate = (): Locator => this.page.getByRole('button', { name: 'Text Templates' })
|
||||
relatedIssues = (): Locator => this.page.getByRole('button', { name: 'Related issues' })
|
||||
classes = (): Locator => this.page.getByRole('button', { name: 'Classes' })
|
||||
enums = (): Locator => this.page.getByRole('button', { name: 'Enums' })
|
||||
inviteSettings = (): Locator => this.page.getByRole('button', { name: 'Invite settings' })
|
||||
|
||||
async selectWorkspaceSettingsTab (button: ButtonType): Promise<void> {
|
||||
switch (button) {
|
||||
case ButtonType.Owners:
|
||||
await this.owners().click()
|
||||
break
|
||||
case ButtonType.Spaces:
|
||||
await this.spaces().click()
|
||||
break
|
||||
case ButtonType.Branding:
|
||||
await this.branding().click()
|
||||
break
|
||||
case ButtonType.TextTemplate:
|
||||
await this.textTemplate().click()
|
||||
break
|
||||
case ButtonType.RelatedIssues:
|
||||
await this.relatedIssues().click()
|
||||
break
|
||||
case ButtonType.Classes:
|
||||
await this.classes().click()
|
||||
break
|
||||
case ButtonType.Enums:
|
||||
await this.enums().click()
|
||||
break
|
||||
case ButtonType.InviteSettings:
|
||||
await this.inviteSettings().click()
|
||||
break
|
||||
default:
|
||||
throw new Error('Unknown button type')
|
||||
}
|
||||
}
|
||||
}
|
81
tests/sanity/tests/text/issueOnboardingText.ts
Normal file
81
tests/sanity/tests/text/issueOnboardingText.ts
Normal file
@ -0,0 +1,81 @@
|
||||
export const helloAndWelcomeToHuly = [
|
||||
'Hello and Welcome to Huly! 🌟 Embark on an exciting journey to master our next-generation project management tool.',
|
||||
"As you tackle these initial issues, you'll uncover essential features and ProTips designed to streamline your workflow.",
|
||||
"Once you're familiar with Huly, feel free to delete these starter issues or share them with your team.",
|
||||
'Start by Creating Your First Issue',
|
||||
'Simply press C from any view to create a new issue.',
|
||||
'You can also click the New Issue button for the same action.',
|
||||
"Dynamic Features of Your Issue Editor: Huly's issue editor is versatile, supporting Markdown for rich text formatting and offering several advanced features:",
|
||||
'Real-Time Collaborative Editor for Issue Descriptions: Uniquely designed for team synergy, the issue description in Huly allows for real-time, collaborative editing.',
|
||||
'Your team can work together on the same description simultaneously, enhancing productivity and collaboration.',
|
||||
'Enhanced Communication in Comments: Although comments are not collaboratively editable, you can still enrich them with @mentions, videos, and emojis.',
|
||||
'This flexibility ensures clear and engaging communication across your team.',
|
||||
'Enhance Team Collaboration:',
|
||||
'Use @mention to involve teammates or reference other items within Huly, making collaboration seamless.',
|
||||
'Drag and drop images or videos into your issues and comments for a comprehensive and visual communication experience.',
|
||||
'Add emojis ✅ to bring personality and clarity to your discussions.',
|
||||
'Dive into the world of Huly, where creating impactful issues and harnessing the power of collaborative project management is just the beginning.',
|
||||
'Discover the ease and efficiency of managing your projects with us!'
|
||||
]
|
||||
|
||||
export const toolsAndTimeBlocking = [
|
||||
'In Huly, Todos and Issues serve distinct yet interconnected purposes.',
|
||||
'While Issues are collaborative and represent various processes like a Feature Development cycle, Todos are personalized tasks crucial for advancing these processes.',
|
||||
'Please read more about Todos here @Understanding Todos in Huly.',
|
||||
'Step-by-Step Guide to Managing a Todo',
|
||||
'Assign the Issue to Yourself: First, ensure the Issue is assigned to you. Change its status from Backlog to Todo, as shown in the image below:',
|
||||
"Todo Creation in Personal Planner: Once you've done this, Huly automatically creates a corresponding Todo in your Personal Planner:",
|
||||
"Find Your Unscheduled Todo: In your Personal Planner, you'll find the newly created Todo listed as Unscheduled.",
|
||||
"Scheduling Your Todo: It’s time to plan when to work on this Todo. Let's schedule it from 15:00 to 17:00.",
|
||||
'You can do this either by dragging the Todo to your desired time slot on the Calendar or by opening the Todo and adding one or more work slots:',
|
||||
'Tracking Progress: After scheduling the Todo, the state of the corresponding Task in Huly changes to In Progress.',
|
||||
'The system also accounts for the 2 hours of work committed to the task, which in this case is @HI-2.',
|
||||
'In the upcoming sections of this tutorial, we’ll explore the multifaceted benefits and applications of Todos in process management, planning, and execution within Huly.',
|
||||
'Example of such benefits is @Team Planning in Huly.',
|
||||
'Stay tuned to learn how to make the most out of this powerful feature!'
|
||||
]
|
||||
|
||||
export const navigationHully = [
|
||||
'In Huly, we offer three intuitive ways to navigate and manage your workflow: using the Command Line, Keyboard Shortcuts, or the Mouse.',
|
||||
'Each method is designed to enhance your productivity and ease of use within the application.',
|
||||
'1. Command Line - The Power of Cmd/Ctrl + K:',
|
||||
"Cmd/Ctrl + K: This is one of Huly's most powerful features. Use this command line shortcut to swiftly search for items or execute any action within the application. It's your go-to tool for quick navigation and task management.",
|
||||
'2. Keyboard Shortcuts - For the Shortcut Enthusiast:',
|
||||
'Discovering Shortcuts: If keyboard shortcuts are your preference, Huly has you covered. Access a comprehensive list of shortcuts by clicking on Help & Support located in the lower-left corner of the application. These shortcuts are designed to streamline your workflow and save you time.',
|
||||
'3. Mouse Navigation - Contextual Menus and More:',
|
||||
"Right-Click for Contextual Menus: Prefer using a mouse? Right-click on any issue to open contextual menus. These menus provide easy access to various actions and are also an excellent way to familiarize yourself with Huly's keyboard shortcuts.",
|
||||
"Learning and Flexibility: Whether you are a fan of quick command-line actions, efficient keyboard shortcuts, or the traditional mouse-click approach, Huly adapts to your style. These navigation methods not only offer flexibility but also help you learn the application's functionality more deeply. Try them out and find the one that best suits your workflow!"
|
||||
]
|
||||
|
||||
export const connectToGithub = [
|
||||
"Huly's bi-directional integration with GitHub brings together the best of both platforms.",
|
||||
'This integration means that activities on GitHub, including Issues, Pull Requests (PRs), Comments, and Change Requests, are instantly updated in your synchronized Huly project, and vice versa.',
|
||||
'Key Features of Huly-GitHub Integration:',
|
||||
'Bi-Directional Synchronization: Ensures real-time updates between Huly and GitHub, providing a cohesive project management experience.',
|
||||
'Milestone-Based Board Management: Huly Milestones correspond to boards in GitHub Projects, maintaining a two-way synchronization for effective board management.',
|
||||
'Flexible Repository Management: Manage individual repositories or entire GitHub organizations and handle multiple GitHub repositories within a single Huly Project.',
|
||||
'Empowered by Huly Automation Capabilities:',
|
||||
'Integration with Huly Automation: Synchronizing your GitHub projects with Huly unlocks additional automation features like Todos and Team Planning, streamlining your project management processes.',
|
||||
'Efficient Workflows: Automations integrate tasks like assignments, status updates, and scheduling, making your workflow more efficient and reducing manual workload.',
|
||||
'Freedom and Flexibility:',
|
||||
'Non-restrictive Use: You have the freedom to stop using Huly at any time. If you decide to discontinue Huly, all your project information will remain intact in GitHub.',
|
||||
"Data Continuity: There's no risk of losing your project data. Even after dropping Huly, your GitHub projects will retain all their information and history.",
|
||||
'Setting Up Your Integration:',
|
||||
'Create a New Project in Huly: Start by creating the project you wish to synchronize with GitHub.',
|
||||
"Navigate to Integrations: In your Huly workspace, go to the 'Integrations' section.",
|
||||
"Connect and Install: Choose 'Connect GitHub' and install the Huly app in your GitHub account or organization.",
|
||||
'Repository Selection and Mapping: Select the GitHub repository you want to sync, and then map it to the corresponding project in Huly.',
|
||||
"Leverage the power of Huly's advanced features with your GitHub projects and enjoy a more streamlined project management experience.",
|
||||
"Remember, you're always in control and can choose to use Huly as per your project needs without any commitment."
|
||||
]
|
||||
|
||||
export const proTip = [
|
||||
'Issue Peek is one hundreds little nice Huly features.',
|
||||
'Turn on/off with the space bar.',
|
||||
'To scroll through issues, type J/K or move the mouse.'
|
||||
]
|
||||
|
||||
export const customizeViewsAndDisplay = [
|
||||
'Customize grouping and sort order of your list and choose what properties show up with Display Options:',
|
||||
'Use Filters to narrow down objects by values of their fields:'
|
||||
]
|
@ -2,6 +2,7 @@ import { Browser, BrowserContext, Locator, Page, expect } from '@playwright/test
|
||||
import { allure } from 'allure-playwright'
|
||||
import { faker } from '@faker-js/faker'
|
||||
import { TestData } from './chat/types'
|
||||
import path from 'path'
|
||||
|
||||
export const PlatformURI = process.env.PLATFORM_URI as string
|
||||
export const PlatformTransactor = process.env.PLATFORM_TRANSACTOR as string
|
||||
@ -34,6 +35,7 @@ export const userName = faker.internet.userName()
|
||||
export const firstName = faker.person.firstName()
|
||||
export const lastName = faker.person.lastName()
|
||||
export const channelName = faker.lorem.word()
|
||||
export const email = faker.internet.email()
|
||||
|
||||
function toHex (value: number, chars: number): string {
|
||||
const result = value.toString(16)
|
||||
@ -117,3 +119,41 @@ export async function checkIfUrlContains (page: Page, url: string): Promise<void
|
||||
export async function waitForNetworIdle (page: Page, timeout = 2000): Promise<void> {
|
||||
await Promise.race([page.waitForLoadState('networkidle'), new Promise((resolve) => setTimeout(resolve, timeout))])
|
||||
}
|
||||
|
||||
// Check for text in the page
|
||||
export const checkTextChunksVisibility = async (page: Page, textChunks: string[]): Promise<void> => {
|
||||
for (const textChunk of textChunks) {
|
||||
await expect(page.locator(`text=${textChunk}`)).toBeVisible()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the file path for a given file name located in the same directory as the test.
|
||||
*
|
||||
* @param fileName - name of the file to be resolved
|
||||
* @returns - resolved file path
|
||||
*/
|
||||
|
||||
function resolveFilePath (fileName: string): string {
|
||||
return path.resolve(__dirname, '.', 'files', fileName)
|
||||
}
|
||||
|
||||
/**
|
||||
* Uploads a single file using a file chooser in Playwright.
|
||||
*
|
||||
* @param page - Playwright Page object
|
||||
* @param fileName - name of the file to be uploaded
|
||||
* @param fileUploadTestId - test ID of the file input element (default: '@upload-file')
|
||||
*/
|
||||
export async function uploadFile (page: Page, fileName: string, fileUploadTestId = 'Attached photo'): Promise<void> {
|
||||
const uploadFileElement = page.getByText(fileUploadTestId)
|
||||
|
||||
const [fileChooser] = await Promise.all([page.waitForEvent('filechooser'), uploadFileElement.click()])
|
||||
|
||||
// Resolve the file path using the 'resolveFilePath' function
|
||||
const filePath = resolveFilePath(fileName)
|
||||
await fileChooser.setFiles(filePath)
|
||||
|
||||
// Replace with a more reliable condition for determining when the upload is complete, if possible.
|
||||
await page.waitForTimeout(2000)
|
||||
}
|
||||
|
181
tests/sanity/tests/workspace/onboarding-workspace.spec.ts
Normal file
181
tests/sanity/tests/workspace/onboarding-workspace.spec.ts
Normal file
@ -0,0 +1,181 @@
|
||||
import { SignUpData } from '../model/common-types'
|
||||
import { IssuesDetailsPage } from '../model/tracker/issues-details-page'
|
||||
import { IssuesPage } from '../model/tracker/issues-page'
|
||||
import { LeftSideMenuPage } from '../model/left-side-menu-page'
|
||||
import { LoginPage } from '../model/login-page'
|
||||
import { SelectWorkspacePage } from '../model/select-workspace-page'
|
||||
import { SignUpPage } from '../model/signup-page'
|
||||
import * as text from '../text/issueOnboardingText'
|
||||
import { test } from '@playwright/test'
|
||||
import { generateId, checkTextChunksVisibility, uploadFile } from '../utils'
|
||||
import { NotificationPage } from '../model/notification-page'
|
||||
import { UserProfilePage } from '../model/profile/user-profile-page'
|
||||
import { ApiEndpoint } from '../API/Api'
|
||||
|
||||
test.describe.skip('Workspace tests', () => {
|
||||
let loginPage: LoginPage
|
||||
let signUpPage: SignUpPage
|
||||
let selectWorkspacePage: SelectWorkspacePage
|
||||
let leftSideMenuPage: LeftSideMenuPage
|
||||
let issuesPage: IssuesPage
|
||||
let issuesDetailsPage: IssuesDetailsPage
|
||||
let notificationPage: NotificationPage
|
||||
let userProfilePage: UserProfilePage
|
||||
let api: ApiEndpoint
|
||||
|
||||
test.beforeEach(async ({ page, request }) => {
|
||||
loginPage = new LoginPage(page)
|
||||
signUpPage = new SignUpPage(page)
|
||||
selectWorkspacePage = new SelectWorkspacePage(page)
|
||||
leftSideMenuPage = new LeftSideMenuPage(page)
|
||||
issuesPage = new IssuesPage(page)
|
||||
issuesDetailsPage = new IssuesDetailsPage(page)
|
||||
notificationPage = new NotificationPage(page)
|
||||
userProfilePage = new UserProfilePage(page)
|
||||
api = new ApiEndpoint(request)
|
||||
})
|
||||
test('Create a workspace from onboarding', async ({ page }) => {
|
||||
const newUser: SignUpData = {
|
||||
firstName: `FirstName-${generateId()}`,
|
||||
lastName: `LastName-${generateId()}`,
|
||||
email: `sanity-email+${generateId()}@gmail.com`,
|
||||
password: '1234'
|
||||
}
|
||||
const newWorkspaceName = `New Workspace Name - ${generateId(2)}`
|
||||
await loginPage.goto()
|
||||
await loginPage.clickSignUp()
|
||||
await signUpPage.signUp(newUser)
|
||||
await selectWorkspacePage.createWorkspace(newWorkspaceName)
|
||||
await leftSideMenuPage.clickTracker()
|
||||
await issuesPage.checkIssuesCount('Hello and Welcome to Huly! 🌟', 1)
|
||||
await issuesPage.checkIssuesCount('Todos and Time Blocking 🗓️', 1)
|
||||
await issuesPage.checkIssuesCount('Navigating Huly: Three Efficient Ways', 1)
|
||||
await issuesPage.checkIssuesCount('Connect GitHub with Huly (', 1)
|
||||
await issuesPage.checkIssuesCount('✨ProTip: Mouse over this', 1)
|
||||
await issuesPage.checkIssuesCount('Customize views with Display', 1)
|
||||
|
||||
await issuesPage.openIssueById('HI-1')
|
||||
})
|
||||
|
||||
test('check the content of the onboarding tracker', async ({ page }) => {
|
||||
const newUser: SignUpData = {
|
||||
firstName: `FirstName-${generateId()}`,
|
||||
lastName: `LastName-${generateId()}`,
|
||||
email: `sanity-email+${generateId()}@gmail.com`,
|
||||
password: '1234'
|
||||
}
|
||||
const newWorkspaceName = `New Workspace Name - ${generateId(2)}`
|
||||
await loginPage.goto()
|
||||
await loginPage.clickSignUp()
|
||||
await signUpPage.signUp(newUser)
|
||||
|
||||
await selectWorkspacePage.createWorkspace(newWorkspaceName)
|
||||
|
||||
await leftSideMenuPage.clickTracker()
|
||||
await issuesPage.openIssueById('HI-1')
|
||||
await checkTextChunksVisibility(page, text.helloAndWelcomeToHuly)
|
||||
await issuesDetailsPage.clickCloseIssueButton()
|
||||
|
||||
await issuesPage.openIssueById('HI-2')
|
||||
await checkTextChunksVisibility(page, text.toolsAndTimeBlocking)
|
||||
await issuesDetailsPage.clickCloseIssueButton()
|
||||
|
||||
await issuesPage.openIssueById('HI-3')
|
||||
await checkTextChunksVisibility(page, text.navigationHully)
|
||||
await issuesDetailsPage.clickCloseIssueButton()
|
||||
|
||||
await issuesPage.openIssueById('HI-4')
|
||||
await checkTextChunksVisibility(page, text.connectToGithub)
|
||||
await issuesDetailsPage.clickCloseIssueButton()
|
||||
|
||||
await issuesPage.openIssueById('HI-5')
|
||||
await checkTextChunksVisibility(page, text.proTip)
|
||||
await issuesDetailsPage.clickCloseIssueButton()
|
||||
|
||||
await issuesPage.openIssueById('HI-6')
|
||||
await checkTextChunksVisibility(page, text.customizeViewsAndDisplay)
|
||||
})
|
||||
|
||||
test('check the content of the notification', async ({ page }) => {
|
||||
const newUser: SignUpData = {
|
||||
firstName: `FirstName-${generateId()}`,
|
||||
lastName: `LastName-${generateId()}`,
|
||||
email: `sanity-email+${generateId()}@gmail.com`,
|
||||
password: '1234'
|
||||
}
|
||||
const newWorkspaceName = `New Workspace Name - ${generateId(2)}`
|
||||
await loginPage.goto()
|
||||
await loginPage.clickSignUp()
|
||||
await signUpPage.signUp(newUser)
|
||||
await selectWorkspacePage.createWorkspace(newWorkspaceName)
|
||||
await leftSideMenuPage.clickNotification()
|
||||
await notificationPage.clickOnNotification('HI-1')
|
||||
await checkTextChunksVisibility(page, text.helloAndWelcomeToHuly)
|
||||
})
|
||||
|
||||
test('User is able to upload pictures', async ({ page }) => {
|
||||
const newUser: SignUpData = {
|
||||
firstName: `FirstName-${generateId()}`,
|
||||
lastName: `LastName-${generateId()}`,
|
||||
email: `sanity-email+${generateId()}@gmail.com`,
|
||||
password: '1234'
|
||||
}
|
||||
const newWorkspaceName = `New Workspace Name - ${generateId(2)}`
|
||||
await loginPage.goto()
|
||||
await loginPage.linkSignUp().click()
|
||||
await signUpPage.signUp(newUser)
|
||||
await selectWorkspacePage.createWorkspace(newWorkspaceName)
|
||||
await leftSideMenuPage.buttonTracker().click()
|
||||
await userProfilePage.openProfileMenu()
|
||||
await userProfilePage.clickSettings()
|
||||
await userProfilePage.clickAccountSettings()
|
||||
await userProfilePage.openUserAvatarMenu()
|
||||
await uploadFile(page, 'Testingo.png')
|
||||
await userProfilePage.clickSavaAvatarButton()
|
||||
})
|
||||
|
||||
test('User is able to change workspace', async ({ page }) => {
|
||||
const newUser: SignUpData = {
|
||||
firstName: `FirstName-${generateId()}`,
|
||||
lastName: `LastName-${generateId()}`,
|
||||
email: `sanity-email+${generateId()}@gmail.com`,
|
||||
password: '1234'
|
||||
}
|
||||
const newWorkspaceName = `New Workspace Name - ${generateId(2)}`
|
||||
const newWorkspaceName2 = `New Workspace Name - ${generateId(2)}`
|
||||
await loginPage.goto()
|
||||
await loginPage.linkSignUp().click()
|
||||
await signUpPage.signUp(newUser)
|
||||
await selectWorkspacePage.createWorkspace(newWorkspaceName)
|
||||
await api.createWorkspaceWithLogin(newWorkspaceName2, newUser.email, '1234')
|
||||
await userProfilePage.openProfileMenu()
|
||||
await userProfilePage.clickSettings()
|
||||
await userProfilePage.clickSelectWorkspace()
|
||||
await selectWorkspacePage.selectWorkspace(newWorkspaceName2)
|
||||
await selectWorkspacePage.clickCreateWorkspaceLogo()
|
||||
await selectWorkspacePage.checkIfWorkspaceExists(newWorkspaceName2)
|
||||
})
|
||||
|
||||
test('User is able to change password', async () => {
|
||||
const newUser: SignUpData = {
|
||||
firstName: `FirstName-${generateId()}`,
|
||||
lastName: `LastName-${generateId()}`,
|
||||
email: `sanity-email+${generateId()}@gmail.com`,
|
||||
password: '1234'
|
||||
}
|
||||
const newWorkspaceName = `New Workspace Name - ${generateId(2)}`
|
||||
const newWorkspaceName2 = `New Workspace Name - ${generateId(2)}`
|
||||
await loginPage.goto()
|
||||
await loginPage.linkSignUp().click()
|
||||
await signUpPage.signUp(newUser)
|
||||
await selectWorkspacePage.createWorkspace(newWorkspaceName)
|
||||
await userProfilePage.openProfileMenu()
|
||||
await userProfilePage.clickSettings()
|
||||
await userProfilePage.changePassword('1234', '4321')
|
||||
await userProfilePage.clickOnSignOutButton()
|
||||
await loginPage.login(newUser.email, '4321')
|
||||
await selectWorkspacePage.selectWorkspace(newWorkspaceName2)
|
||||
await selectWorkspacePage.clickCreateWorkspaceLogo()
|
||||
await selectWorkspacePage.checkIfWorkspaceExists(newWorkspaceName2)
|
||||
})
|
||||
})
|
167
tests/sanity/tests/workspace/workspace-settings.spec.ts
Normal file
167
tests/sanity/tests/workspace/workspace-settings.spec.ts
Normal file
@ -0,0 +1,167 @@
|
||||
import { SignUpData } from '../model/common-types'
|
||||
import { LoginPage } from '../model/login-page'
|
||||
import { SelectWorkspacePage } from '../model/select-workspace-page'
|
||||
import { SignUpPage } from '../model/signup-page'
|
||||
import { test } from '@playwright/test'
|
||||
import { generateId, uploadFile } from '../utils'
|
||||
import { UserProfilePage } from '../model/profile/user-profile-page'
|
||||
import { ButtonType, WorkspaceSettingsPage } from '../model/workspace/workspace-settings-page'
|
||||
import { OwnersPage } from '../model/workspace/owner-pages'
|
||||
import { faker } from '@faker-js/faker'
|
||||
import { ClassesPage } from '../model/workspace/classes-pages'
|
||||
|
||||
test.describe('Workspace tests', () => {
|
||||
let loginPage: LoginPage
|
||||
let signUpPage: SignUpPage
|
||||
let selectWorkspacePage: SelectWorkspacePage
|
||||
let userProfilePage: UserProfilePage
|
||||
let workspaceSettingsPage: WorkspaceSettingsPage
|
||||
let ownersPage: OwnersPage
|
||||
let newUser: SignUpData
|
||||
let classesPage: ClassesPage
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
loginPage = new LoginPage(page)
|
||||
signUpPage = new SignUpPage(page)
|
||||
selectWorkspacePage = new SelectWorkspacePage(page)
|
||||
userProfilePage = new UserProfilePage(page)
|
||||
workspaceSettingsPage = new WorkspaceSettingsPage(page)
|
||||
ownersPage = new OwnersPage(page)
|
||||
classesPage = new ClassesPage(page)
|
||||
})
|
||||
|
||||
test('User the owner is showing inside the owner tab', async ({ page }) => {
|
||||
newUser = {
|
||||
firstName: faker.person.firstName(),
|
||||
lastName: faker.person.lastName(),
|
||||
email: faker.internet.email(),
|
||||
password: '1234'
|
||||
}
|
||||
const newWorkspaceName = `New Workspace Name - ${generateId(2)}`
|
||||
await loginPage.goto()
|
||||
await loginPage.linkSignUp().click()
|
||||
await signUpPage.signUp(newUser)
|
||||
await selectWorkspacePage.createWorkspace(newWorkspaceName)
|
||||
await userProfilePage.openProfileMenu()
|
||||
await userProfilePage.clickSettings()
|
||||
await workspaceSettingsPage.selectWorkspaceSettingsTab(ButtonType.Owners)
|
||||
await ownersPage.checkIfOwnerExists(newUser.firstName)
|
||||
})
|
||||
|
||||
test('User is able to set himself as an spaces admin', async ({ page }) => {
|
||||
newUser = {
|
||||
firstName: faker.person.firstName(),
|
||||
lastName: faker.person.lastName(),
|
||||
email: faker.internet.email(),
|
||||
password: '1234'
|
||||
}
|
||||
const newWorkspaceName = `New Workspace Name - ${generateId(2)}`
|
||||
await loginPage.goto()
|
||||
await loginPage.linkSignUp().click()
|
||||
await signUpPage.signUp(newUser)
|
||||
await selectWorkspacePage.createWorkspace(newWorkspaceName)
|
||||
await userProfilePage.openProfileMenu()
|
||||
await userProfilePage.clickSettings()
|
||||
await workspaceSettingsPage.selectWorkspaceSettingsTab(ButtonType.Spaces)
|
||||
await ownersPage.addMember(newUser.firstName)
|
||||
})
|
||||
|
||||
test('User is able to change workspace picture', async ({ page }) => {
|
||||
newUser = {
|
||||
firstName: faker.person.firstName(),
|
||||
lastName: faker.person.lastName(),
|
||||
email: faker.internet.email(),
|
||||
password: '1234'
|
||||
}
|
||||
const newWorkspaceName = `New Workspace Name - ${generateId(2)}`
|
||||
await loginPage.goto()
|
||||
await loginPage.linkSignUp().click()
|
||||
await signUpPage.signUp(newUser)
|
||||
await selectWorkspacePage.createWorkspace(newWorkspaceName)
|
||||
await userProfilePage.openProfileMenu()
|
||||
await userProfilePage.clickSettings()
|
||||
await workspaceSettingsPage.selectWorkspaceSettingsTab(ButtonType.Branding)
|
||||
await ownersPage.clickOnWorkspaceLogo()
|
||||
await uploadFile(page, 'cat3.jpeg')
|
||||
await ownersPage.saveUploadedLogo()
|
||||
await ownersPage.checkIfPictureIsUploaded()
|
||||
})
|
||||
|
||||
test('User is able to create template', async ({ page }) => {
|
||||
newUser = {
|
||||
firstName: faker.person.firstName(),
|
||||
lastName: faker.person.lastName(),
|
||||
email: faker.internet.email(),
|
||||
password: '1234'
|
||||
}
|
||||
const newWorkspaceName = `New Workspace Name - ${generateId(2)}`
|
||||
const newTemplateName = faker.word.words(2)
|
||||
await loginPage.goto()
|
||||
await loginPage.linkSignUp().click()
|
||||
await signUpPage.signUp(newUser)
|
||||
await selectWorkspacePage.createWorkspace(newWorkspaceName)
|
||||
await userProfilePage.openProfileMenu()
|
||||
await userProfilePage.clickSettings()
|
||||
await workspaceSettingsPage.selectWorkspaceSettingsTab(ButtonType.TextTemplate)
|
||||
await ownersPage.createTemplateWithName(newTemplateName)
|
||||
})
|
||||
|
||||
test('User is able to see all the classes', async ({ page }) => {
|
||||
newUser = {
|
||||
firstName: faker.person.firstName(),
|
||||
lastName: faker.person.lastName(),
|
||||
email: faker.internet.email(),
|
||||
password: '1234'
|
||||
}
|
||||
const newWorkspaceName = `New Workspace Name - ${generateId(2)}`
|
||||
await loginPage.goto()
|
||||
await loginPage.linkSignUp().click()
|
||||
await signUpPage.signUp(newUser)
|
||||
await selectWorkspacePage.createWorkspace(newWorkspaceName)
|
||||
await userProfilePage.openProfileMenu()
|
||||
await userProfilePage.clickSettings()
|
||||
await workspaceSettingsPage.selectWorkspaceSettingsTab(ButtonType.Classes)
|
||||
await classesPage.checkIfClassesExists()
|
||||
})
|
||||
|
||||
test('User is able to create Enum', async ({ page }) => {
|
||||
newUser = {
|
||||
firstName: faker.person.firstName(),
|
||||
lastName: faker.person.lastName(),
|
||||
email: faker.internet.email(),
|
||||
password: '1234'
|
||||
}
|
||||
const newWorkspaceName = `New Workspace Name - ${generateId(2)}`
|
||||
const enumTitle = faker.word.words(2)
|
||||
const enumName = faker.word.words(2)
|
||||
await loginPage.goto()
|
||||
await loginPage.linkSignUp().click()
|
||||
await signUpPage.signUp(newUser)
|
||||
await selectWorkspacePage.createWorkspace(newWorkspaceName)
|
||||
await userProfilePage.openProfileMenu()
|
||||
await userProfilePage.clickSettings()
|
||||
await workspaceSettingsPage.selectWorkspaceSettingsTab(ButtonType.Enums)
|
||||
await ownersPage.createEnumWithName(enumTitle, enumName)
|
||||
})
|
||||
|
||||
// Seems that there is currently a bug
|
||||
test.skip('User is able to create Enums', async ({ page }) => {
|
||||
newUser = {
|
||||
firstName: faker.person.firstName(),
|
||||
lastName: faker.person.lastName(),
|
||||
email: faker.internet.email(),
|
||||
password: '1234'
|
||||
}
|
||||
const newWorkspaceName = `New Workspace Name - ${generateId(2)}`
|
||||
const enumTitle = faker.word.words(2)
|
||||
const enumName = faker.word.words(2)
|
||||
await loginPage.goto()
|
||||
await loginPage.linkSignUp().click()
|
||||
await signUpPage.signUp(newUser)
|
||||
await selectWorkspacePage.createWorkspace(newWorkspaceName)
|
||||
await userProfilePage.openProfileMenu()
|
||||
await userProfilePage.clickSettings()
|
||||
await workspaceSettingsPage.selectWorkspaceSettingsTab(ButtonType.InviteSettings)
|
||||
await ownersPage.createEnumWithName(enumTitle, enumName)
|
||||
})
|
||||
})
|
Loading…
Reference in New Issue
Block a user