mirror of
https://github.com/hcengineering/platform.git
synced 2024-11-22 03:14:40 +03:00
parent
6f7e95e233
commit
dd809242b1
@ -30,21 +30,23 @@
|
||||
</script>
|
||||
|
||||
{#if channels?.length === 0}
|
||||
<CircleButton
|
||||
icon={IconAdd}
|
||||
size={'small'}
|
||||
selected
|
||||
on:click={(ev) =>
|
||||
showPopup(contact.component.SocialEditor, { values: channels }, ev.target, (result) => {
|
||||
if (result !== undefined) {
|
||||
dispatch('change', result)
|
||||
}
|
||||
})}
|
||||
/>
|
||||
<span class="ml-2"><Label label={presentation.string.AddSocialLinks} /></span>
|
||||
<div id="channels-edit">
|
||||
<CircleButton
|
||||
icon={IconAdd}
|
||||
size={'small'}
|
||||
selected
|
||||
on:click={(ev) =>
|
||||
showPopup(contact.component.SocialEditor, { values: channels }, ev.target, (result) => {
|
||||
if (result !== undefined) {
|
||||
dispatch('change', result)
|
||||
}
|
||||
})}
|
||||
/>
|
||||
<span class="ml-2"><Label label={presentation.string.AddSocialLinks} /></span>
|
||||
</div>
|
||||
{:else}
|
||||
<ChannelsView value={channels} size={'small'} {integrations} on:click />
|
||||
<div class="ml-1">
|
||||
<div id="channels-edit" class="ml-1">
|
||||
<CircleButton
|
||||
icon={contact.icon.Edit}
|
||||
size={'small'}
|
||||
|
@ -60,7 +60,6 @@
|
||||
let container: HTMLElement
|
||||
|
||||
</script>
|
||||
|
||||
<div class="caption-color cursor-pointer" bind:this={container} class:empty={selected === undefined} on:click|preventDefault={() => {
|
||||
if (!opened) {
|
||||
opened = true
|
||||
|
@ -30,6 +30,10 @@
|
||||
const query = createQuery()
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
let items: ListItem[] = []
|
||||
let selected: ListItem | undefined
|
||||
let resolved = false
|
||||
|
||||
query.query(contact.class.Organization, {}, (res) => {
|
||||
items = res.map((org) => {
|
||||
return {
|
||||
@ -41,12 +45,13 @@
|
||||
if (value !== undefined) {
|
||||
selected = items.find((p) => p._id === value)
|
||||
}
|
||||
resolved = true
|
||||
})
|
||||
|
||||
let items: ListItem[] = []
|
||||
let selected: ListItem | undefined
|
||||
|
||||
$: setValue(selected)
|
||||
$: if (resolved) {
|
||||
setValue(selected)
|
||||
}
|
||||
|
||||
function setValue (selected: ListItem | undefined): void {
|
||||
if (selected === undefined) {
|
||||
|
@ -60,7 +60,7 @@
|
||||
async function createApplication () {
|
||||
const state = await client.findOne(task.class.State, { space: doc.space })
|
||||
if (state === undefined) {
|
||||
throw new Error('create application: state not found')
|
||||
throw new Error(`create application: state not found space:${doc.space}`)
|
||||
}
|
||||
const sequence = await client.findOne(task.class.Sequence, { attachedTo: recruit.class.Applicant })
|
||||
if (sequence === undefined) {
|
||||
|
@ -23,15 +23,13 @@
|
||||
Data,
|
||||
Doc,
|
||||
FindResult,
|
||||
generateId,
|
||||
Hierarchy,
|
||||
MixinData,
|
||||
generateId, MixinData,
|
||||
Ref,
|
||||
TxProcessor
|
||||
} from '@anticrm/core'
|
||||
import login from '@anticrm/login'
|
||||
import { getMetadata, getResource, setPlatformStatus, unknownError } from '@anticrm/platform'
|
||||
import presentation, {
|
||||
import {
|
||||
Card,
|
||||
createQuery,
|
||||
EditableAvatar,
|
||||
@ -271,7 +269,7 @@
|
||||
const categoriesMap = new Map(Array.from(categories.map((it) => [it._id, it])))
|
||||
|
||||
const newSkills: TagReference[] = []
|
||||
|
||||
|
||||
// Create missing tag elemnts
|
||||
for (const s of doc.skills ?? []) {
|
||||
const title = s.trim().toLowerCase()
|
||||
|
@ -17,13 +17,13 @@
|
||||
import calendar from '@anticrm/calendar'
|
||||
import contact, { Contact } from '@anticrm/contact'
|
||||
import { OrganizationSelector } from '@anticrm/contact-resources'
|
||||
import { getClient, UserBox, UserBoxList, UserInfo } from '@anticrm/presentation'
|
||||
import { getClient, UserBox, UserBoxList } from '@anticrm/presentation'
|
||||
import type { Review } from '@anticrm/recruit'
|
||||
import { StyledTextBox } from '@anticrm/text-editor'
|
||||
import { Grid, Label, showPanel, StylishEdit } from '@anticrm/ui'
|
||||
import view from '@anticrm/view'
|
||||
import { createEventDispatcher, onMount } from 'svelte'
|
||||
import recruit from '../../plugin'
|
||||
import view from '@anticrm/view'
|
||||
|
||||
export let object: Review
|
||||
|
||||
@ -80,21 +80,6 @@
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Grid column={2}>
|
||||
<StylishEdit
|
||||
label={calendar.string.Location}
|
||||
bind:value={object.location}
|
||||
on:change={() => client.update(object, { location: object.location })}
|
||||
/>
|
||||
<div class="antiComponentBox">
|
||||
<OrganizationSelector
|
||||
bind:value={object.company}
|
||||
label={recruit.string.Company}
|
||||
on:change={() => client.update(object, { company: object.company })}
|
||||
/>
|
||||
</div>
|
||||
</Grid>
|
||||
<div class="flex-row">
|
||||
<div class="mt-4 mb-2">
|
||||
<Label label={calendar.string.Participants} />
|
||||
|
@ -90,11 +90,11 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="flex-between trans-title mb-3">
|
||||
<div id='create-template' class="flex-between trans-title mb-3">
|
||||
<Label label={setting.string.Templates}/>
|
||||
<CircleButton icon={IconAdd} size="medium" on:click={createTemplate} />
|
||||
</div>
|
||||
<div class="flex-col overflow-y-auto">
|
||||
<div id='templates' class="flex-col overflow-y-auto">
|
||||
{#each templates as t (t._id)}
|
||||
<div class="ac-column__list-item" class:selected={t._id === template?._id} on:click={() => select(t)}>
|
||||
<AttributeEditor maxWidth={'15rem'} _class={task.class.KanbanTemplate} object={t} key="title"/>
|
||||
|
@ -77,7 +77,7 @@
|
||||
<ShowMore ignore={!showTitle}>
|
||||
<div class:tags-container={showTitle} class:mt-4={showTitle}>
|
||||
<div class="flex flex-reverse">
|
||||
<div class="ml-4">
|
||||
<div id='add-tag' class="ml-4">
|
||||
<Tooltip label={tags.string.AddTagTooltip} props={{ word: keyLabel }}>
|
||||
<CircleButton icon={IconAdd} size={'small'} selected on:click={addTag} />
|
||||
</Tooltip>
|
||||
|
@ -65,7 +65,7 @@
|
||||
<div class="ap-header">
|
||||
<EditWithIcon icon={IconSearch} bind:value={search} placeholder={tags.string.SearchCreate} focus>
|
||||
<svelte:fragment slot="extra">
|
||||
<div class="ml-27" bind:this={anchor}>
|
||||
<div id='new-tag' class="ml-27" bind:this={anchor}>
|
||||
<ActionIcon
|
||||
label={tags.string.AddNowTooltip}
|
||||
labelProps={{ word: title }}
|
||||
|
@ -57,7 +57,7 @@
|
||||
async function createTask () {
|
||||
const state = await client.findOne(task.class.State, { space: _space })
|
||||
if (state === undefined) {
|
||||
throw new Error('create application: state not found')
|
||||
throw new Error('create task: state not found')
|
||||
}
|
||||
|
||||
const sequence = await client.findOne(task.class.Sequence, { attachedTo: task.class.Issue })
|
||||
|
@ -66,7 +66,7 @@
|
||||
|
||||
<div class="ac-body columns">
|
||||
<div class="ac-column">
|
||||
<div class="flex-between trans-title mb-3">
|
||||
<div id='create-template' class="flex-between trans-title mb-3">
|
||||
<Label label={templatesPlugin.string.TemplatesHeader} />
|
||||
<CircleButton icon={IconAdd} on:click={addTemplate} />
|
||||
</div>
|
||||
|
@ -218,7 +218,7 @@
|
||||
value={getValue(object, attribute.key)}
|
||||
{...attribute.props}
|
||||
/>
|
||||
<div class="antiTable-cells__firstCell-menuRow" on:click={(ev) => showMenu(ev, object, row)}>
|
||||
<div id='context-menu' class="antiTable-cells__firstCell-menuRow" on:click={(ev) => showMenu(ev, object, row)}>
|
||||
<MoreV size={'small'} />
|
||||
</div>
|
||||
</div>
|
||||
|
@ -262,7 +262,7 @@
|
||||
notify={hasNotification}
|
||||
/>
|
||||
<div class="flex-center">
|
||||
<div
|
||||
<div id="profile-button"
|
||||
class="cursor-pointer"
|
||||
on:click|stopPropagation={(el) => {
|
||||
showPopup(AccountPopup, {}, 'account')
|
||||
|
@ -64,7 +64,7 @@
|
||||
{:else}
|
||||
{#await actions() then actionItems}
|
||||
{#if actionItems.length === 1}
|
||||
<div class="an-element__tool">
|
||||
<div id={_id} class="an-element__tool">
|
||||
<ActionIcon
|
||||
label={actionItems[0].label}
|
||||
icon={actionItems[0].icon}
|
||||
|
@ -53,18 +53,20 @@ abstract class MongoAdapterBase extends TxProcessor {
|
||||
const translated: any = {}
|
||||
for (const key in query) {
|
||||
const value = (query as any)[key]
|
||||
|
||||
const tkey = this.checkMixinKey(key, clazz)
|
||||
if (value !== null && typeof value === 'object') {
|
||||
const keys = Object.keys(value)
|
||||
if (keys[0] === '$like') {
|
||||
const pattern = value.$like as string
|
||||
translated[key] = {
|
||||
translated[tkey] = {
|
||||
$regex: `^${pattern.split('%').map(it => escapeLikeForRegexp(it)).join('.*')}$`,
|
||||
$options: 'i'
|
||||
}
|
||||
continue
|
||||
}
|
||||
}
|
||||
translated[key] = value
|
||||
translated[tkey] = value
|
||||
}
|
||||
const baseClass = this.hierarchy.getBaseClass(clazz)
|
||||
const classes = this.hierarchy.getDescendants(baseClass)
|
||||
|
9
tests/build-reload.sh
Executable file
9
tests/build-reload.sh
Executable file
@ -0,0 +1,9 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Restore workspace contents in mongo/elastic
|
||||
rush build
|
||||
rush bundle
|
||||
rush docker:build
|
||||
|
||||
# Re-assign user to workspace.
|
||||
docker-compose -p sanity up $1 -d --force-recreate
|
@ -12,7 +12,9 @@
|
||||
"format": "prettier --write tests && eslint --fix tests",
|
||||
"ci": "playwright install --with-deps chromium",
|
||||
"test": "",
|
||||
"uitest": "playwright test --browser chromium --reporter list,html -c ./tests/playwright.config.ts"
|
||||
"uitest": "playwright test --browser chromium --reporter list,html -c ./tests/playwright.config.ts",
|
||||
"debug": "playwright test --browser chromium -c ./tests/playwright.config.ts --debug --headed",
|
||||
"codegen": "playwright codegen --load-storage storage.json http://localhost:8083/workbench%3Acomponent%3AWorkbenchApp"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@anticrm/platform-rig": "~0.6.0",
|
||||
|
26
tests/sanity/storage.json
Normal file
26
tests/sanity/storage.json
Normal file
@ -0,0 +1,26 @@
|
||||
{
|
||||
"cookies": [],
|
||||
"origins": [
|
||||
{
|
||||
"origin": "http://localhost:8083",
|
||||
"localStorage": [
|
||||
{
|
||||
"name": "login:metadata:LoginEmail",
|
||||
"value": "user1"
|
||||
},
|
||||
{
|
||||
"name": "login:metadata:LoginToken",
|
||||
"value": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJlbWFpbCI6InVzZXIxIiwid29ya3NwYWNlIjoic2FuaXR5LXdzIn0.hfUCqePHO-WNps2by4B-CYGKIpDpLG0WVCUUtU-SVI4"
|
||||
},
|
||||
{
|
||||
"name": "login:metadata:CurrentWorkspace",
|
||||
"value": "sanity-ws"
|
||||
},
|
||||
{
|
||||
"name": "login:metadata:LoginEndpoint",
|
||||
"value": "ws://localhost:3334"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -1,31 +1,49 @@
|
||||
import { test, expect } from '@playwright/test'
|
||||
import { openWorkbench } from './utils'
|
||||
import { expect, test } from '@playwright/test'
|
||||
import { generateId, openWorkbench } from './utils'
|
||||
|
||||
test.describe('contact tests', () => {
|
||||
test('create-contact', async ({ page }) => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
// Create user and workspace
|
||||
await openWorkbench(page)
|
||||
|
||||
})
|
||||
test('create-contact', async ({ page }) => {
|
||||
// Create a new context with the saved storage state.
|
||||
await page.locator('[id="app-contact\\:string\\:Contacts"]').click()
|
||||
|
||||
await page.click('button:has-text("Contact")')
|
||||
|
||||
await (await page.locator('.ap-menuItem')).locator('text=Person').click()
|
||||
|
||||
const first = 'Elton-' + generateId(5)
|
||||
const last = 'John-' + generateId(5)
|
||||
|
||||
const firstName = page.locator('[placeholder="John"]')
|
||||
await firstName.click()
|
||||
await firstName.fill('Elton')
|
||||
await firstName.fill(first)
|
||||
|
||||
const lastName = page.locator('[placeholder="Appleseed"]')
|
||||
await lastName.click()
|
||||
await lastName.fill('John')
|
||||
await lastName.fill(last)
|
||||
|
||||
await page.locator('.antiCard').locator('button:has-text("Create")').click()
|
||||
})
|
||||
test('contact-search', async ({ page }) => {
|
||||
// Create user and workspace
|
||||
await openWorkbench(page)
|
||||
test('create-organization', async ({ page }) => {
|
||||
await page.locator('[id="app-contact\\:string\\:Contacts"]').click()
|
||||
|
||||
await page.click('button:has-text("Contact")')
|
||||
|
||||
await (await page.locator('.ap-menuItem')).locator('text=Organization').click()
|
||||
|
||||
const orgName = 'Organization' + generateId(5)
|
||||
|
||||
const firstName = page.locator('[placeholder="Apple"]')
|
||||
await firstName.click()
|
||||
await firstName.fill(orgName)
|
||||
|
||||
await page.locator('.antiCard').locator('button:has-text("Create")').click()
|
||||
await expect(page.locator(`text=${orgName}`)).toBeVisible()
|
||||
})
|
||||
test('contact-search', async ({ page }) => {
|
||||
await page.locator('[id="app-contact\\:string\\:Contacts"]').click()
|
||||
|
||||
await expect(page.locator('text=Marina M.')).toBeVisible()
|
||||
@ -43,4 +61,35 @@ test.describe('contact tests', () => {
|
||||
await expect(page.locator('text=Rosamund Chen')).toBeVisible()
|
||||
expect(await page.locator('.antiTable-body__row').count()).toBeGreaterThan(5)
|
||||
})
|
||||
|
||||
test('delete-contact', async ({ page }) => {
|
||||
// Create a new context with the saved storage state.
|
||||
await page.locator('[id="app-contact\\:string\\:Contacts"]').click()
|
||||
|
||||
await page.click('button:has-text("Contact")')
|
||||
|
||||
await (await page.locator('.ap-menuItem')).locator('text=Person').click()
|
||||
|
||||
const first = 'Elton-' + generateId(5)
|
||||
const last = 'John-' + generateId(5)
|
||||
|
||||
const firstName = page.locator('[placeholder="John"]')
|
||||
await firstName.click()
|
||||
await firstName.fill(first)
|
||||
|
||||
const lastName = page.locator('[placeholder="Appleseed"]')
|
||||
await lastName.click()
|
||||
await lastName.fill(last)
|
||||
|
||||
await page.locator('.antiCard').locator('button:has-text("Create")').click()
|
||||
|
||||
// Click #context-menu svg
|
||||
await page.hover(`td:has-text("${first} ${last}")`)
|
||||
await page.click('#context-menu')
|
||||
await page.click('text="Delete"')
|
||||
// Click text=Ok
|
||||
await page.click('text=Ok')
|
||||
|
||||
await expect(page.locator(`td:has-text("${first} ${last}")`)).toHaveCount(0)
|
||||
})
|
||||
})
|
||||
|
@ -1,24 +1,28 @@
|
||||
import { expect, test } from '@playwright/test'
|
||||
import { openWorkbench } from './utils'
|
||||
import { generateId, openWorkbench } from './utils'
|
||||
|
||||
test.describe('recruit tests', () => {
|
||||
test('create-candidate', async ({ page }) => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
// Create user and workspace
|
||||
await openWorkbench(page)
|
||||
|
||||
})
|
||||
test('create-candidate', async ({ page, context }) => {
|
||||
await page.locator('[id="app-recruit\\:string\\:RecruitApplication"]').click()
|
||||
|
||||
await page.click('text=Candidates')
|
||||
|
||||
await page.click('button:has-text("Candidate")')
|
||||
|
||||
const first = 'Elton-' + generateId(4)
|
||||
const last = 'John-' + generateId(4)
|
||||
|
||||
const firstName = page.locator('[placeholder="John"]')
|
||||
await firstName.click()
|
||||
await firstName.fill('EltonC')
|
||||
await firstName.fill(first)
|
||||
|
||||
const lastName = page.locator('[placeholder="Appleseed"]')
|
||||
await lastName.click()
|
||||
await lastName.fill('JohnC')
|
||||
await lastName.fill(last)
|
||||
|
||||
const title = page.locator('[placeholder="Title"]')
|
||||
await title.click()
|
||||
@ -32,11 +36,19 @@ test.describe('recruit tests', () => {
|
||||
})
|
||||
|
||||
test('create-application', async ({ page }) => {
|
||||
// Create user and workspace
|
||||
await openWorkbench(page)
|
||||
await page.locator('[id="app-recruit\\:string\\:RecruitApplication"]').click()
|
||||
|
||||
const vacancyId = 'My vacancy ' + generateId(4)
|
||||
|
||||
await page.locator('[id="app-recruit\\:string\\:RecruitApplication"]').click()
|
||||
|
||||
await page.locator('text=Vacancies').click()
|
||||
|
||||
await page.click('button:has-text("Vacancy")')
|
||||
await page.fill('[placeholder="Software\\ Engineer"]', vacancyId)
|
||||
await page.click('button:has-text("Create")')
|
||||
await page.locator(`text=${vacancyId}`).click()
|
||||
|
||||
await page.click('text=Candidates')
|
||||
|
||||
await page.click('text=Candidates')
|
||||
@ -48,41 +60,37 @@ test.describe('recruit tests', () => {
|
||||
|
||||
await page.click('span:has-text("Select vacancy")')
|
||||
|
||||
await page.click('button:has-text("Software Engineer")')
|
||||
await page.click(`button:has-text("${vacancyId}")`)
|
||||
|
||||
await page.click('text=Create Cancel >> button')
|
||||
await page.click('button:has-text("Create")')
|
||||
|
||||
await page.click('text=APP-4')
|
||||
await page.locator(`tr:has-text("${vacancyId}") >> text=APP-`).click()
|
||||
await page.click('text=Assigned recruiter Not selected')
|
||||
await page.click('button:has-text("Rosamund Chen")')
|
||||
})
|
||||
|
||||
test('create-vacancy', async ({ page }) => {
|
||||
// Create user and workspace
|
||||
await openWorkbench(page)
|
||||
const vacancyId = 'My vacancy ' + generateId(4)
|
||||
|
||||
await page.locator('[id="app-recruit\\:string\\:RecruitApplication"]').click()
|
||||
|
||||
await page.locator('text=Vacancies').click()
|
||||
|
||||
await page.click('button:has-text("Vacancy")')
|
||||
await page.fill('[placeholder="Software\\ Engineer"]', 'My vacancy')
|
||||
await page.click('text=Create Cancel >> button')
|
||||
await page.locator('text=My vacancy').click()
|
||||
await page.fill('[placeholder="Software\\ Engineer"]', vacancyId)
|
||||
await page.click('button:has-text("Create")')
|
||||
await page.locator(`text=${vacancyId}`).click()
|
||||
|
||||
// Create Applicatio n1
|
||||
await page.click('text=Application')
|
||||
await page.click('button:has-text("Application")')
|
||||
await page.click('text=Not selected')
|
||||
await page.click('button:has-text("Alex P.")')
|
||||
await page.click('text=Create Cancel >> button')
|
||||
await page.click('button:has-text("Create")')
|
||||
|
||||
await expect(page.locator('text=APP-').first()).toBeVisible()
|
||||
await expect(page.locator('text=Alex P.').first()).toBeVisible()
|
||||
})
|
||||
test('use-kanban', async ({ page }) => {
|
||||
// Create user and workspace
|
||||
await openWorkbench(page)
|
||||
|
||||
await page.locator('[id="app-recruit\\:string\\:RecruitApplication"]').click()
|
||||
|
||||
await page.locator('text=Vacancies').click()
|
||||
@ -96,15 +104,12 @@ test.describe('recruit tests', () => {
|
||||
})
|
||||
|
||||
test('application-search', async ({ page }) => {
|
||||
// Create user and workspace
|
||||
await openWorkbench(page)
|
||||
|
||||
await page.locator('[id="app-recruit\\:string\\:RecruitApplication"]').click()
|
||||
|
||||
await page.locator('text=Vacancies').click()
|
||||
await page.click('text=Software Engineer')
|
||||
|
||||
await expect(page.locator('text=Andrey P.')).toBeVisible()
|
||||
await expect(page.locator('text=Marina M.')).toBeVisible()
|
||||
expect(await page.locator('.antiTable-body__row').count()).toBeGreaterThan(2)
|
||||
|
||||
const searchBox = page.locator('[placeholder="Search"]')
|
||||
@ -116,7 +121,45 @@ test.describe('recruit tests', () => {
|
||||
await searchBox.fill('')
|
||||
await searchBox.press('Enter')
|
||||
|
||||
await expect(page.locator('text=Andrey P.')).toBeVisible()
|
||||
await expect(page.locator('text=Marina M.')).toBeVisible()
|
||||
expect(await page.locator('.antiTable-body__row').count()).toBeGreaterThan(2)
|
||||
})
|
||||
|
||||
test('create-interview', async ({ page }) => {
|
||||
await page.locator('[id="app-recruit\\:string\\:RecruitApplication"]').click()
|
||||
|
||||
const interviewId = 'My interview ' + generateId(4)
|
||||
|
||||
await page.locator('[id="app-recruit\\:string\\:RecruitApplication"]').click()
|
||||
|
||||
await page.hover('text=Reviews')
|
||||
await page.click('[name="tooltip-recruit:string:CreateReviewCategory"]')
|
||||
|
||||
await page.fill('[placeholder="Interview"]', interviewId)
|
||||
await page.click('button:has-text("Create")')
|
||||
await page.locator(`text=${interviewId}`).click()
|
||||
|
||||
// Click button:has-text("Review")
|
||||
await page.click('button:has-text("Review")')
|
||||
// Click [placeholder="\ "]
|
||||
await page.click('[placeholder="\\ "]')
|
||||
// Fill [placeholder="\ "]
|
||||
await page.fill('[placeholder="\\ "]', 'Meet PEterson')
|
||||
// Click text=Location Company Company >> [placeholder="\ "]
|
||||
await page.click('text=Location Company Company >> [placeholder="\\ "]')
|
||||
// Fill text=Location Company Company >> [placeholder="\ "]
|
||||
await page.fill('text=Location Company Company >> [placeholder="\\ "]', 'NSK')
|
||||
// Click text=Company Company >> div
|
||||
await page.click('text=Company Company >> div')
|
||||
// Click button:has-text("Apple")
|
||||
await page.click('button:has-text("Apple")')
|
||||
// Click text=Candidate Not selected >> span
|
||||
await page.click('text=Candidate Not selected >> span')
|
||||
// Click button:has-text("Andrey P.")
|
||||
await page.click('button:has-text("Andrey P.")')
|
||||
// Click text=Create
|
||||
await page.click('text=Create')
|
||||
|
||||
await page.click('td:has-text("RVE-")')
|
||||
})
|
||||
})
|
||||
|
99
tests/sanity/tests/settings.spec.ts
Normal file
99
tests/sanity/tests/settings.spec.ts
Normal file
@ -0,0 +1,99 @@
|
||||
import { expect, test } from '@playwright/test'
|
||||
import { generateId, openWorkbench } from './utils'
|
||||
|
||||
test.describe('contact tests', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
// Create user and workspace
|
||||
await openWorkbench(page)
|
||||
})
|
||||
test('update-profile', async ({ page, context }) => {
|
||||
// Go to http://localhost:8083/workbench%3Acomponent%3AWorkbenchApp
|
||||
await page.goto('http://localhost:8083/workbench%3Acomponent%3AWorkbenchApp')
|
||||
// Click #profile-button
|
||||
await page.click('#profile-button')
|
||||
// Click text=Setting
|
||||
await page.click('text=Setting')
|
||||
await expect(page).toHaveURL('http://localhost:8083/workbench%3Acomponent%3AWorkbenchApp/setting%3Aids%3ASettingApp/setting')
|
||||
// Click text=Edit profile
|
||||
await page.click('text=Edit profile')
|
||||
await expect(page).toHaveURL('http://localhost:8083/workbench%3Acomponent%3AWorkbenchApp/setting%3Aids%3ASettingApp/profile')
|
||||
// Click [placeholder="Location"]
|
||||
await page.click('[placeholder="Location"]')
|
||||
// Fill [placeholder="Location"]
|
||||
await page.fill('[placeholder="Location"]', 'LoPlaza')
|
||||
// Click .flex-center.icon-button
|
||||
await page.click('#channels-edit >> .flex-center.icon-button')
|
||||
// Click [placeholder="john\.appleseed\@apple\.com"]
|
||||
await page.click('[placeholder="john\\.appleseed\\@apple\\.com"]')
|
||||
// Fill [placeholder="john\.appleseed\@apple\.com"]
|
||||
await page.fill('[placeholder="john\\.appleseed\\@apple\\.com"]', 'wer@qwe.com')
|
||||
// Click text=Apply
|
||||
await page.click('text=Apply')
|
||||
})
|
||||
test('create-template', async ({ page }) => {
|
||||
// Go to http://localhost:8083/workbench%3Acomponent%3AWorkbenchApp
|
||||
await page.goto('http://localhost:8083/workbench%3Acomponent%3AWorkbenchApp')
|
||||
// Click #profile-button
|
||||
await page.click('#profile-button')
|
||||
// Click text=Templates
|
||||
await page.click('text=Templates')
|
||||
await expect(page).toHaveURL('http://localhost:8083/workbench%3Acomponent%3AWorkbenchApp/setting%3Aids%3ASettingApp/message-templates')
|
||||
// Go to http://localhost:8083/workbench%3Acomponent%3AWorkbenchApp/setting%3Aids%3ASettingApp/message-templates
|
||||
await page.goto('http://localhost:8083/workbench%3Acomponent%3AWorkbenchApp/setting%3Aids%3ASettingApp/message-templates')
|
||||
// Click .flex-center.icon-button
|
||||
await page.click('#create-template >> .flex-center.icon-button')
|
||||
// Click [placeholder="New\ template"]
|
||||
await page.click('[placeholder="New\\ template"]')
|
||||
// Fill [placeholder="New\ template"]
|
||||
await page.fill('[placeholder="New\\ template"]', 't1')
|
||||
|
||||
await page.fill('.ProseMirror', 'some text value')
|
||||
await page.press('.ProseMirror', 'Enter')
|
||||
await page.fill('.ProseMirror', 'some more value')
|
||||
|
||||
// Click text=Save template
|
||||
await page.click('text=Save template')
|
||||
// Click text=Edit template
|
||||
await page.click('text=Edit template')
|
||||
// Click text=Template valuesome more value
|
||||
await page.fill('.ProseMirror', 'some more2 value')
|
||||
// Click text=Save template
|
||||
await page.click('text=Save template')
|
||||
// Click text=Edit template
|
||||
})
|
||||
|
||||
test('manage-status-templates', async ({ page }) => {
|
||||
// Go to http://localhost:8083/workbench%3Acomponent%3AWorkbenchApp
|
||||
await page.goto('http://localhost:8083/workbench%3Acomponent%3AWorkbenchApp')
|
||||
// Click #profile-button
|
||||
await page.click('#profile-button')
|
||||
// Click text=Manage Statuses
|
||||
await page.click('text=Manage Statuses')
|
||||
await expect(page).toHaveURL('http://localhost:8083/workbench%3Acomponent%3AWorkbenchApp/setting%3Aids%3ASettingApp/statuses')
|
||||
// Click text=Vacancies
|
||||
await page.click('text=Vacancies')
|
||||
// Click #create-template div
|
||||
await page.click('#create-template div')
|
||||
const tid = 'template-' + generateId()
|
||||
const t = page.locator('#templates >> .container:has-text("New Template")').last()
|
||||
await t.click()
|
||||
await t.locator('input').fill(tid)
|
||||
// await page.locator(`#templates >> .container:has-text("${tid}")`).type('Enter')
|
||||
|
||||
// Click text=Active statuses >> div
|
||||
await page.click('text=Active statuses >> div')
|
||||
|
||||
const s1 = page.locator('.container:has-text("New State")').first()
|
||||
await s1.click()
|
||||
await s1.locator('input').fill('State1')
|
||||
|
||||
await page.click('text=Active statuses >> div')
|
||||
const s2 = page.locator('.container:has-text("New State")').first()
|
||||
await s2.click()
|
||||
await s2.locator('input').fill('State2')
|
||||
await page.click('text=Active statuses >> div')
|
||||
const s3 = page.locator('.container:has-text("New State")').first()
|
||||
await s3.click()
|
||||
await s3.locator('input').fill('State3')
|
||||
})
|
||||
})
|
99
tests/sanity/tests/tags.spec.ts
Normal file
99
tests/sanity/tests/tags.spec.ts
Normal file
@ -0,0 +1,99 @@
|
||||
import { expect, test } from '@playwright/test'
|
||||
import { generateId, openWorkbench } from './utils'
|
||||
|
||||
test.describe('recruit tests', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
// Create user and workspace
|
||||
await openWorkbench(page)
|
||||
})
|
||||
test('create-candidate-with-skill', async ({ page }) => {
|
||||
// Go to http://localhost:8083/workbench%3Acomponent%3AWorkbenchApp
|
||||
await page.goto('http://localhost:8083/workbench%3Acomponent%3AWorkbenchApp')
|
||||
// Click [id="app-recruit\:string\:RecruitApplication"]
|
||||
await page.click('[id="app-recruit\\:string\\:RecruitApplication"]')
|
||||
await expect(page).toHaveURL('http://localhost:8083/workbench%3Acomponent%3AWorkbenchApp/recruit%3Aapp%3ARecruit')
|
||||
// Click text=Candidates
|
||||
await page.click('text=Candidates')
|
||||
await expect(page).toHaveURL('http://localhost:8083/workbench%3Acomponent%3AWorkbenchApp/recruit%3Aapp%3ARecruit/candidates')
|
||||
// Click button:has-text("Candidate")
|
||||
await page.click('button:has-text("Candidate")')
|
||||
// Fill [placeholder="John"]
|
||||
await page.fill('[placeholder="John"]', 'Petr')
|
||||
// Click [placeholder="Appleseed"]
|
||||
await page.click('[placeholder="Appleseed"]')
|
||||
// Fill [placeholder="Appleseed"]
|
||||
await page.fill('[placeholder="Appleseed"]', 'Dooliutl')
|
||||
// Click .ml-4 .tooltip-trigger .flex-center
|
||||
await page.click('#add-tag')
|
||||
// Click text=Add/Create Skill Suggested Cancel >> button
|
||||
await page.click('#new-tag')
|
||||
// Fill [placeholder="Please\ type\ Skill\ title"]
|
||||
await page.fill('[placeholder="Please\\ type\\ Skill\\ title"]', 's1')
|
||||
// Click text=Create Skill s1 Please type description here Category Other Create Cancel >> button
|
||||
await page.click('text=Create Skill s1 Please type description here Category Other Create Cancel >> button')
|
||||
// Click text=s1
|
||||
await page.click('text=s1')
|
||||
// Click :nth-match(:text("Cancel"), 2)
|
||||
await page.click(':nth-match(:text("Cancel"), 2)')
|
||||
// Click button:has-text("Create")
|
||||
await page.click('button:has-text("Create")')
|
||||
})
|
||||
|
||||
test('create-tag-candidate', async ({ page }) => {
|
||||
// Go to http://localhost:8083/workbench%3Acomponent%3AWorkbenchApp
|
||||
await page.goto('http://localhost:8083/workbench%3Acomponent%3AWorkbenchApp')
|
||||
// Click [id="app-recruit\:string\:RecruitApplication"]
|
||||
await page.click('[id="app-recruit\\:string\\:RecruitApplication"]')
|
||||
await expect(page).toHaveURL('http://localhost:8083/workbench%3Acomponent%3AWorkbenchApp/recruit%3Aapp%3ARecruit')
|
||||
// Click text=Skills
|
||||
await page.click('text=Skills')
|
||||
await expect(page).toHaveURL('http://localhost:8083/workbench%3Acomponent%3AWorkbenchApp/recruit%3Aapp%3ARecruit/skills')
|
||||
// Click button:has-text("Skill")
|
||||
await page.click('button:has-text("Skill")')
|
||||
// Click [placeholder="Please\ type\ skill\ title"]
|
||||
await page.click('[placeholder="Please\\ type\\ skill\\ title"]')
|
||||
// Fill [placeholder="Please\ type\ skill\ title"]
|
||||
await page.fill('[placeholder="Please\\ type\\ skill\\ title"]', 'java')
|
||||
// Click button:has-text("Create")
|
||||
await page.click('button:has-text("Create")')
|
||||
// Click button:has-text("Skill")
|
||||
await page.click('button:has-text("Skill")')
|
||||
// Fill [placeholder="Please\ type\ skill\ title"]
|
||||
await page.fill('[placeholder="Please\\ type\\ skill\\ title"]', 'MongoDB')
|
||||
// Click button:has-text("Create")
|
||||
await page.click('button:has-text("Create")')
|
||||
// Click button:has-text("Skill")
|
||||
await page.click('button:has-text("Skill")')
|
||||
// Fill [placeholder="Please\ type\ skill\ title"]
|
||||
await page.fill('[placeholder="Please\\ type\\ skill\\ title"]', 'C++')
|
||||
// Click button:has-text("Create")
|
||||
await page.click('button:has-text("Create")')
|
||||
// Click text=Candidates
|
||||
await page.click('text=Candidates')
|
||||
await expect(page).toHaveURL('http://localhost:8083/workbench%3Acomponent%3AWorkbenchApp/recruit%3Aapp%3ARecruit/candidates')
|
||||
// Click button:has-text("Candidate")
|
||||
await page.click('button:has-text("Candidate")')
|
||||
// Click #add-tag div div
|
||||
await page.click('#add-tag div div')
|
||||
// Click text=java
|
||||
await page.click('text=java')
|
||||
// Click :nth-match(:text("Cancel"), 2)
|
||||
await page.click(':nth-match(:text("Cancel"), 2)')
|
||||
// Click [placeholder="John"]
|
||||
await page.click('[placeholder="John"]')
|
||||
// Fill [placeholder="John"]
|
||||
const first = 'first-' + generateId().slice(0, 4)
|
||||
await page.fill('[placeholder="John"]', first)
|
||||
// Click [placeholder="Appleseed"]
|
||||
await page.click('[placeholder="Appleseed"]')
|
||||
// Fill [placeholder="Appleseed"]
|
||||
const last = 'last-' + generateId().slice(0, 4)
|
||||
await page.fill('[placeholder="Appleseed"]', last)
|
||||
// Click button:has-text("Create")
|
||||
await page.click('button:has-text("Create")')
|
||||
// Click text=q w
|
||||
await page.click(`text=${first} ${last}`)
|
||||
// Click text=java
|
||||
await expect(page.locator('text=java').first()).toBeVisible()
|
||||
})
|
||||
})
|
@ -17,3 +17,38 @@ export async function openWorkbench (page: Page): Promise<void> {
|
||||
await page.goto('http://localhost:8083/workbench%3Acomponent%3AWorkbenchApp')
|
||||
await page.waitForSelector('[id="app-contact\\:string\\:Contacts"]')
|
||||
}
|
||||
|
||||
function toHex (value: number, chars: number): string {
|
||||
const result = value.toString(16)
|
||||
if (result.length < chars) {
|
||||
return '0'.repeat(chars - result.length) + result
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
let counter = (Math.random() * (1 << 24)) | 0
|
||||
const random = toHex((Math.random() * (1 << 24)) | 0, 6) + toHex((Math.random() * (1 << 16)) | 0, 4)
|
||||
|
||||
function timestamp (): string {
|
||||
const time = (Date.now() / 1000) | 0
|
||||
return toHex(time, 8)
|
||||
}
|
||||
|
||||
function count (): string {
|
||||
const val = counter++ & 0xffffff
|
||||
return toHex(val, 6)
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
* @returns
|
||||
*/
|
||||
export function generateId (len = 100): string {
|
||||
const v = (timestamp() + random)
|
||||
let s = v.length - len
|
||||
if (s < 0) {
|
||||
s = 0
|
||||
}
|
||||
const r = v.slice(s, v.length) + count()
|
||||
return r
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user