270 lines
10 KiB
TypeScript
270 lines
10 KiB
TypeScript
import { expect, type Page, test } from '@playwright/test'
|
|
|
|
async function useAdminSession (page: Page) {
|
|
await page.addInitScript(() => {
|
|
sessionStorage.setItem('bolts-session', JSON.stringify({
|
|
username: 'admin',
|
|
role: 'admin',
|
|
token: 'admin-token',
|
|
}))
|
|
})
|
|
}
|
|
|
|
test('admin opens a user file and views a linked entity record', async ({ page }) => {
|
|
let projectTitle = 'Website refresh'
|
|
const projects: Record<string, unknown>[] = [{ id: 42, title: 'Website refresh', owner: 7 }]
|
|
const tasks: Record<string, unknown>[] = []
|
|
const notes: Record<string, unknown>[] = []
|
|
const milestones: Record<string, unknown>[] = []
|
|
const profiles: Record<string, unknown>[] = []
|
|
const projectResponse = () => ({
|
|
entity: {
|
|
id: 3,
|
|
name: 'Project',
|
|
identifier: 'project',
|
|
fields: [
|
|
{ id: 11, name: 'Title', identifier: 'title', type: 'TEXT' },
|
|
{ id: 12, name: 'Owner', identifier: 'owner', type: 'USER' },
|
|
{
|
|
id: 13,
|
|
name: 'Milestones',
|
|
identifier: 'milestones',
|
|
type: 'RELATIONSHIP',
|
|
targetEntityId: 6,
|
|
relationshipType: 'ONE_TO_MANY',
|
|
},
|
|
{
|
|
id: 14,
|
|
name: 'Tasks',
|
|
identifier: 'tasks',
|
|
type: 'RELATIONSHIP',
|
|
targetEntityId: 4,
|
|
relationshipType: 'ONE_TO_MANY',
|
|
},
|
|
],
|
|
},
|
|
values: { id: 42, title: projectTitle, owner: 7 },
|
|
children: [{
|
|
entity: {
|
|
id: 4,
|
|
name: 'Task',
|
|
identifier: 'task',
|
|
fields: [
|
|
{ id: 20, name: 'Description', identifier: 'description', type: 'TEXT' },
|
|
{
|
|
id: 22,
|
|
name: 'Notes',
|
|
identifier: 'notes',
|
|
type: 'RELATIONSHIP',
|
|
targetEntityId: 5,
|
|
relationshipType: 'ONE_TO_MANY',
|
|
},
|
|
],
|
|
},
|
|
relationshipField: {
|
|
id: 14,
|
|
name: 'Tasks',
|
|
identifier: 'tasks',
|
|
type: 'RELATIONSHIP',
|
|
targetEntityId: 4,
|
|
relationshipType: 'ONE_TO_MANY',
|
|
},
|
|
records: tasks,
|
|
}, {
|
|
entity: {
|
|
id: 6,
|
|
name: 'Milestone',
|
|
identifier: 'milestone',
|
|
fields: [{ id: 40, name: 'Label', identifier: 'label', type: 'TEXT' }],
|
|
},
|
|
relationshipField: {
|
|
id: 13,
|
|
name: 'Milestones',
|
|
identifier: 'milestones',
|
|
type: 'RELATIONSHIP',
|
|
targetEntityId: 6,
|
|
relationshipType: 'ONE_TO_MANY',
|
|
},
|
|
records: milestones,
|
|
}],
|
|
})
|
|
|
|
await useAdminSession(page)
|
|
await page.route('**/api/users', route => route.fulfill({
|
|
json: [{ id: 7, username: 'alex', role: 'user' }],
|
|
}))
|
|
await page.route('**/api/users/7/file', route => route.fulfill({
|
|
json: {
|
|
user: { id: 7, username: 'alex', role: 'user' },
|
|
linkedEntities: [{
|
|
entity: {
|
|
id: 3,
|
|
name: 'Project',
|
|
identifier: 'project',
|
|
fields: [
|
|
{ id: 11, name: 'Title', identifier: 'title', type: 'TEXT' },
|
|
{ id: 12, name: 'Owner', identifier: 'owner', type: 'USER' },
|
|
],
|
|
},
|
|
relationshipField: { id: 12, name: 'Owner', identifier: 'owner', type: 'USER' },
|
|
records: projects,
|
|
}, {
|
|
entity: {
|
|
id: 8,
|
|
name: 'Profile',
|
|
identifier: 'profile',
|
|
fields: [
|
|
{ id: 50, name: 'Biography', identifier: 'biography', type: 'TEXT' },
|
|
{ id: 51, name: 'User', identifier: 'user', type: 'USER', relationshipType: 'ONE_TO_ONE' },
|
|
],
|
|
},
|
|
relationshipField: {
|
|
id: 51,
|
|
name: 'User',
|
|
identifier: 'user',
|
|
type: 'USER',
|
|
relationshipType: 'ONE_TO_ONE',
|
|
},
|
|
records: profiles,
|
|
}],
|
|
},
|
|
}))
|
|
await page.route('**/api/users/7/children/Project/12', async route => {
|
|
const values = new URLSearchParams(route.request().postData() ?? '')
|
|
const created = { id: 43, title: values.get('title'), owner: 7 }
|
|
projects.push(created)
|
|
await route.fulfill({
|
|
status: 201,
|
|
json: { entity: projectResponse().entity, values: created, children: [] },
|
|
})
|
|
})
|
|
await page.route('**/api/users/7/children/Profile/51', async route => {
|
|
const values = new URLSearchParams(route.request().postData() ?? '')
|
|
const created = { id: 70, biography: values.get('biography'), user: 7 }
|
|
profiles.push(created)
|
|
await route.fulfill({
|
|
status: 201,
|
|
json: { entity: { id: 8, name: 'Profile' }, values: created, children: [] },
|
|
})
|
|
})
|
|
await page.route('**/api/users/7/entities/Project/records/42', async route => {
|
|
if (route.request().method() === 'PATCH') {
|
|
const values = new URLSearchParams(route.request().postData() ?? '')
|
|
projectTitle = values.get('title') ?? projectTitle
|
|
}
|
|
await route.fulfill({ json: projectResponse() })
|
|
})
|
|
await page.route('**/api/users/7/entities/Project/records/42/children/Task/14', async route => {
|
|
const values = new URLSearchParams(route.request().postData() ?? '')
|
|
const created = { id: 55, description: values.get('description'), notes: null }
|
|
tasks.push(created)
|
|
await route.fulfill({
|
|
status: 201,
|
|
json: {
|
|
entity: projectResponse().children.at(0)!.entity,
|
|
values: created,
|
|
children: [],
|
|
},
|
|
})
|
|
})
|
|
await page.route('**/api/users/7/entities/Project/records/42/children/Milestone/13', async route => {
|
|
const values = new URLSearchParams(route.request().postData() ?? '')
|
|
const created = { id: 60, label: values.get('label') }
|
|
milestones.push(created)
|
|
await route.fulfill({
|
|
status: 201,
|
|
json: { entity: projectResponse().children.at(1)!.entity, values: created, children: [] },
|
|
})
|
|
})
|
|
await page.route('**/api/users/7/entities/Task/records/55', route => route.fulfill({
|
|
json: {
|
|
entity: projectResponse().children.at(0)!.entity,
|
|
values: tasks.at(0),
|
|
children: [{
|
|
entity: {
|
|
id: 5,
|
|
name: 'Note',
|
|
identifier: 'note',
|
|
fields: [
|
|
{ id: 30, name: 'Contents', identifier: 'contents', type: 'TEXT' },
|
|
],
|
|
},
|
|
relationshipField: {
|
|
id: 22,
|
|
name: 'Notes',
|
|
identifier: 'notes',
|
|
type: 'RELATIONSHIP',
|
|
targetEntityId: 5,
|
|
relationshipType: 'ONE_TO_MANY',
|
|
},
|
|
records: notes,
|
|
}],
|
|
},
|
|
}))
|
|
await page.route('**/api/users/7/entities/Task/records/55/children/Note/22', async route => {
|
|
const values = new URLSearchParams(route.request().postData() ?? '')
|
|
const created = { id: 56, contents: values.get('contents') }
|
|
notes.push(created)
|
|
await route.fulfill({
|
|
status: 201,
|
|
json: { entity: { id: 5, name: 'Note', fields: [] }, values: created, children: [] },
|
|
})
|
|
})
|
|
|
|
await page.goto('/users')
|
|
await page.getByRole('link', { name: 'alex' }).click()
|
|
|
|
await expect(page.getByRole('heading', { name: 'alex' })).toBeVisible()
|
|
await expect(page.getByRole('heading', { name: 'Project' })).toBeVisible()
|
|
await expect(page.getByRole('row').filter({ hasText: 'Website refresh' })).toContainText('7')
|
|
|
|
const profile = page.locator('.entity-card').filter({ has: page.getByRole('heading', { name: 'Profile' }) })
|
|
await expect(profile.getByText('No Profile has been created.')).toBeVisible()
|
|
await expect(profile.locator('table')).not.toBeVisible()
|
|
await profile.getByRole('button', { name: 'Create Profile' }).click()
|
|
const profileForm = profile.getByRole('form', { name: 'Create Profile' })
|
|
await profileForm.getByLabel('Biography').fill('Product specialist')
|
|
await profileForm.getByRole('button', { name: 'Create Profile' }).click()
|
|
await expect(profile.getByText('Product specialist')).toBeVisible()
|
|
await expect(profile.getByRole('button', { name: 'Create Profile' })).not.toBeVisible()
|
|
await expect(profile.locator('table')).not.toBeVisible()
|
|
|
|
await page.getByRole('button', { name: 'Add Project' }).click()
|
|
const projectForm = page.getByRole('form', { name: 'Add Project' })
|
|
await projectForm.getByLabel('Title').fill('Mobile application')
|
|
await projectForm.getByRole('button', { name: 'Add Project' }).click()
|
|
await expect(page.getByRole('row').filter({ hasText: 'Mobile application' })).toContainText('7')
|
|
|
|
await page.getByRole('link', { name: 'View Project record 42' }).click()
|
|
await expect(page).toHaveURL('/users/7/entities/Project/records/42')
|
|
await expect(page.getByRole('heading', { name: 'Project #42' })).toBeVisible()
|
|
await expect(page.getByText('Website refresh')).toBeVisible()
|
|
await expect(page.getByText('Owner')).toBeVisible()
|
|
|
|
await page.getByRole('button', { name: 'Add Milestone' }).click()
|
|
const milestoneForm = page.getByRole('form', { name: 'Add Milestone' })
|
|
await milestoneForm.getByLabel('Label').fill('Public beta')
|
|
await milestoneForm.getByRole('button', { name: 'Add Milestone' }).click()
|
|
await expect(page.getByRole('row').filter({ hasText: 'Public beta' })).toBeVisible()
|
|
|
|
await page.getByRole('button', { name: 'Edit record' }).click()
|
|
const editForm = page.getByRole('form', { name: 'Edit record' })
|
|
await editForm.getByLabel('Title').fill('Mobile application')
|
|
await editForm.getByRole('button', { name: 'Save changes' }).click()
|
|
await expect(page.getByText('Mobile application')).toBeVisible()
|
|
|
|
await page.getByRole('button', { name: 'Add Task' }).click()
|
|
const childForm = page.getByRole('form', { name: 'Add Task' })
|
|
await childForm.getByLabel('Description').fill('Prepare launch')
|
|
await childForm.getByRole('button', { name: 'Add Task' }).click()
|
|
await expect(page.getByRole('row').filter({ hasText: 'Prepare launch' })).toBeVisible()
|
|
|
|
await page.getByRole('link', { name: 'View Task record 55' }).click()
|
|
await expect(page.getByRole('heading', { name: 'Task #55' })).toBeVisible()
|
|
await page.getByRole('button', { name: 'Add Note' }).click()
|
|
const noteForm = page.getByRole('form', { name: 'Add Note' })
|
|
await noteForm.getByLabel('Contents').fill('Nested child')
|
|
await noteForm.getByRole('button', { name: 'Add Note' }).click()
|
|
await expect(page.getByRole('row').filter({ hasText: 'Nested child' })).toBeVisible()
|
|
})
|