mirror of
				https://github.com/paperless-ngx/paperless-ngx.git
				synced 2025-11-03 11:07:13 -05:00 
			
		
		
		
	* Add setting to decide whether the edit dialog should automatically close on save * Add the actual button to the ui * Revert "Add the actual button to the ui" This reverts commit e1f5a8bde0e8a2f6bafa2896d6a7e57e70d0c670. * Revert "Add setting to decide whether the edit dialog should automatically close on save" This reverts commit feef3c909b055b4bc4d2884324a4678348e1e536. * Add button for save without exit * Correct save button ordering, ensure perms, update translation strings * fix e2e tests * Add unit testing for save / save & close button --------- Update messages.xlf Update document-detail.component.spec.ts Co-Authored-By: shamoon <4887959+shamoon@users.noreply.github.com>
		
			
				
	
	
		
			150 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			150 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
import { test, expect } from '@playwright/test'
 | 
						|
 | 
						|
const REQUESTS_HAR = 'e2e/document-detail/requests/api-document-detail.har'
 | 
						|
const REQUESTS_HAR2 = 'e2e/document-detail/requests/api-document-detail2.har'
 | 
						|
 | 
						|
test('should activate / deactivate save button when changes are saved', async ({
 | 
						|
  page,
 | 
						|
}) => {
 | 
						|
  await page.routeFromHAR(REQUESTS_HAR, { notFound: 'fallback' })
 | 
						|
  await page.goto('/documents/175/')
 | 
						|
  await page.waitForSelector('app-document-detail app-input-text:first-child')
 | 
						|
  await expect(page.getByTitle('Storage path', { exact: true })).toHaveText(
 | 
						|
    /\w+/
 | 
						|
  )
 | 
						|
  await expect(
 | 
						|
    page.getByRole('button', { name: 'Save', exact: true })
 | 
						|
  ).toBeDisabled()
 | 
						|
  await page.getByTitle('Storage path').getByTitle('Clear all').click()
 | 
						|
  await expect(
 | 
						|
    page.getByRole('button', { name: 'Save', exact: true })
 | 
						|
  ).toBeEnabled()
 | 
						|
})
 | 
						|
 | 
						|
test('should warn on unsaved changes', async ({ page }) => {
 | 
						|
  await page.routeFromHAR(REQUESTS_HAR, { notFound: 'fallback' })
 | 
						|
  await page.goto('/documents/175/')
 | 
						|
  await expect(page.getByTitle('Correspondent', { exact: true })).toHaveText(
 | 
						|
    /\w+/
 | 
						|
  )
 | 
						|
  await expect(
 | 
						|
    page.getByRole('button', { name: 'Save', exact: true })
 | 
						|
  ).toBeDisabled()
 | 
						|
  await page
 | 
						|
    .getByTitle('Storage path', { exact: true })
 | 
						|
    .getByTitle('Clear all')
 | 
						|
    .click()
 | 
						|
  await expect(
 | 
						|
    page.getByRole('button', { name: 'Save', exact: true })
 | 
						|
  ).toBeEnabled()
 | 
						|
  await page.getByRole('button', { name: 'Close', exact: true }).click()
 | 
						|
  await expect(page.getByRole('dialog')).toHaveText(/unsaved changes/)
 | 
						|
  await page.getByRole('button', { name: 'Cancel' }).click()
 | 
						|
  await page.getByRole('link', { name: 'Close all' }).click()
 | 
						|
  await expect(page.getByRole('dialog')).toHaveText(/unsaved changes/)
 | 
						|
})
 | 
						|
 | 
						|
test('should support tab direct navigation', async ({ page }) => {
 | 
						|
  await page.routeFromHAR(REQUESTS_HAR, { notFound: 'fallback' })
 | 
						|
  await page.goto('/documents/175/details')
 | 
						|
  await expect(page.getByRole('tab', { name: 'Details' })).toHaveAttribute(
 | 
						|
    'aria-selected',
 | 
						|
    'true'
 | 
						|
  )
 | 
						|
  await page.goto('/documents/175/content')
 | 
						|
  await expect(page.getByRole('tab', { name: 'Content' })).toHaveAttribute(
 | 
						|
    'aria-selected',
 | 
						|
    'true'
 | 
						|
  )
 | 
						|
  await page.goto('/documents/175/metadata')
 | 
						|
  await expect(page.getByRole('tab', { name: 'Metadata' })).toHaveAttribute(
 | 
						|
    'aria-selected',
 | 
						|
    'true'
 | 
						|
  )
 | 
						|
  await page.goto('/documents/175/notes')
 | 
						|
  await expect(page.getByRole('tab', { name: 'Notes' })).toHaveAttribute(
 | 
						|
    'aria-selected',
 | 
						|
    'true'
 | 
						|
  )
 | 
						|
  await page.goto('/documents/175/permissions')
 | 
						|
  await expect(page.getByRole('tab', { name: 'Permissions' })).toHaveAttribute(
 | 
						|
    'aria-selected',
 | 
						|
    'true'
 | 
						|
  )
 | 
						|
})
 | 
						|
 | 
						|
test('should show a mobile preview', async ({ page }) => {
 | 
						|
  await page.routeFromHAR(REQUESTS_HAR, { notFound: 'fallback' })
 | 
						|
  await page.goto('/documents/175/')
 | 
						|
  await page.setViewportSize({ width: 400, height: 1000 })
 | 
						|
  await expect(page.getByRole('tab', { name: 'Preview' })).toBeVisible()
 | 
						|
  await page.getByRole('tab', { name: 'Preview' }).click()
 | 
						|
  await page.waitForSelector('pdf-viewer')
 | 
						|
})
 | 
						|
 | 
						|
test('should show a list of notes', async ({ page }) => {
 | 
						|
  await page.routeFromHAR(REQUESTS_HAR, { notFound: 'fallback' })
 | 
						|
  await page.goto('/documents/175/notes')
 | 
						|
  await expect(page.locator('app-document-notes')).toBeVisible()
 | 
						|
  await expect(
 | 
						|
    await page.getByRole('button', {
 | 
						|
      name: /delete note/i,
 | 
						|
      includeHidden: true,
 | 
						|
    })
 | 
						|
  ).toHaveCount(4)
 | 
						|
})
 | 
						|
 | 
						|
test('should support note deletion', async ({ page }) => {
 | 
						|
  await page.routeFromHAR(REQUESTS_HAR, { notFound: 'fallback' })
 | 
						|
  await page.goto('/documents/175/notes')
 | 
						|
  await expect(page.locator('app-document-notes')).toBeVisible()
 | 
						|
  const deletePromise = page.waitForRequest(
 | 
						|
    (request) =>
 | 
						|
      request.method() === 'DELETE' &&
 | 
						|
      request.url().includes('/api/documents/175/notes/')
 | 
						|
  )
 | 
						|
  await page
 | 
						|
    .getByRole('button', { name: /delete note/i, includeHidden: true })
 | 
						|
    .first()
 | 
						|
    .click()
 | 
						|
  await deletePromise
 | 
						|
})
 | 
						|
 | 
						|
test('should support note insertion', async ({ page }) => {
 | 
						|
  await page.routeFromHAR(REQUESTS_HAR, { notFound: 'fallback' })
 | 
						|
  await page.goto('/documents/175/notes')
 | 
						|
  await expect(page.locator('app-document-notes')).toBeVisible()
 | 
						|
  await expect(
 | 
						|
    await page.getByRole('button', {
 | 
						|
      name: /delete note/i,
 | 
						|
      includeHidden: true,
 | 
						|
    })
 | 
						|
  ).toHaveCount(4)
 | 
						|
  await page.getByPlaceholder('Enter note').fill('This is a new note')
 | 
						|
  const addPromise = page.waitForRequest((request) => {
 | 
						|
    if (!request.url().includes('/notes/')) {
 | 
						|
      // ignore other requests
 | 
						|
      return true
 | 
						|
    } else {
 | 
						|
      const data = request.postDataJSON()
 | 
						|
      const isValid = data['note'] === 'This is a new note'
 | 
						|
      return (
 | 
						|
        isValid &&
 | 
						|
        request.method() === 'POST' &&
 | 
						|
        request.url().includes('/notes/')
 | 
						|
      )
 | 
						|
    }
 | 
						|
  })
 | 
						|
  await page.getByRole('button', { name: 'Add note' }).click()
 | 
						|
  await addPromise
 | 
						|
})
 | 
						|
 | 
						|
test('should support quick filters', async ({ page }) => {
 | 
						|
  await page.routeFromHAR(REQUESTS_HAR2, { notFound: 'fallback' })
 | 
						|
  await page.goto('/documents/175/details')
 | 
						|
  await page
 | 
						|
    .getByRole('button', { name: 'Filter documents with these Tags' })
 | 
						|
    .click()
 | 
						|
  await expect(page).toHaveURL(/tags__id__all=4&sort=created&reverse=1&page=1/)
 | 
						|
})
 |