Files
payload/test/plugin-seo/e2e.spec.ts
Paul b417c1f61a feat(plugin-seo)!: support overriding default fields via a function instead and fixes bugs regarding localized labels (#8958)
## The SEO plugin now takes in a function to override or add in new
fields
- `fieldOverrides` has been removed
- `fields` is now a function that takes in `defaultFields` and expects
an array of fields in return

This makes it a lot easier for end users to override and extend existing
fields and add new ones. This change also brings this plugin inline with
the pattern that we use in our other plugins.

```ts
// before
seoPlugin({
  fieldOverrides: {
    title: {
      required: true,
    },
  },
  fields: [
    {
      name: 'customField',
      type: 'text',
    }
  ]
})

// after
seoPlugin({
  fields: ({ defaultFields }) => {
    const modifiedFields = defaultFields.map((field) => {
     // Override existing fields
      if ('name' in field && field.name === 'title') {
        return {
          ...field,
          required: true,
        }
      }
      return field
    })

    return [
      ...modifiedFields,

     // Add a new field
      {
        name: 'ogTitle',
        type: 'text',
        label: 'og:title',
      },
    ]
  },
})
```



## Also fixes
- Localization labels not showing up on default fields
- The inability to add before and after inputs to default fields
https://github.com/payloadcms/payload/issues/8893
2024-10-31 06:03:39 +00:00

171 lines
6.1 KiB
TypeScript

import type { Page } from '@playwright/test'
import { expect, test } from '@playwright/test'
import path from 'path'
import { getFileByPath } from 'payload'
import { wait } from 'payload/shared'
import { fileURLToPath } from 'url'
import type { Config, Page as PayloadPage } from './payload-types.js'
import { ensureCompilationIsDone, initPageConsoleErrorCatch } from '../helpers.js'
import { AdminUrlUtil } from '../helpers/adminUrlUtil.js'
import { initPayloadE2ENoConfig } from '../helpers/initPayloadE2ENoConfig.js'
import { TEST_TIMEOUT_LONG } from '../playwright.config.js'
import { mediaSlug } from './shared.js'
const filename = fileURLToPath(import.meta.url)
const dirname = path.dirname(filename)
const { beforeAll, describe } = test
let url: AdminUrlUtil
let page: Page
let id: string
describe('SEO Plugin', () => {
beforeAll(async ({ browser }, testInfo) => {
testInfo.setTimeout(TEST_TIMEOUT_LONG)
const { serverURL, payload } = await initPayloadE2ENoConfig<Config>({ dirname })
url = new AdminUrlUtil(serverURL, 'pages')
const context = await browser.newContext()
page = await context.newPage()
initPageConsoleErrorCatch(page)
const filePath = path.resolve(dirname, './image-1.jpg')
const file = await getFileByPath(filePath)
const mediaDoc = await payload.create({
collection: mediaSlug,
data: {},
file,
})
const createdPage = (await payload.create({
collection: 'pages',
data: {
slug: 'test-page',
meta: {
description: 'This is a test meta description',
image: mediaDoc.id,
ogTitle: 'This is a custom og:title field',
title: 'This is a test meta title',
},
title: 'Test Page',
},
})) as unknown as PayloadPage
id = createdPage.id
await ensureCompilationIsDone({ page, serverURL })
})
describe('Core functionality', () => {
test('Config tab should be merged in correctly', async () => {
await page.goto(url.edit(id))
const contentTabsClass = '.tabs-field__tabs .tabs-field__tab-button'
const firstTab = page.locator(contentTabsClass).nth(0)
await expect(firstTab).toContainText('General')
})
test('Should auto-generate meta title when button is clicked in tabs', async () => {
const contentTabsClass = '.tabs-field__tabs .tabs-field__tab-button'
const autoGenerateButtonClass = '.group-field__wrap .render-fields div:nth-of-type(1) button'
const metaTitleClass = '#field-meta__title'
const secondTab = page.locator(contentTabsClass).nth(1)
await secondTab.click()
const metaTitle = page.locator(metaTitleClass)
await expect(metaTitle).toHaveValue('This is a test meta title')
const autoGenButton = page.locator(autoGenerateButtonClass).nth(0)
await expect(autoGenButton).toContainText('Auto-generate')
await autoGenButton.click()
await expect(metaTitle).toHaveValue('Website.com — Test Page')
})
// todo: Re-enable this test once required attributes are fixed
/* test('Title should be required as per custom override', async () => {
const metaTitleClass = '#field-title'
const metaTitle = page.locator(metaTitleClass).nth(0)
await expect(metaTitle).toHaveAttribute('required', '')
}) */
test('Indicator should be orangered and characters counted', async () => {
const indicatorClass =
'#field-meta > div > div.render-fields.render-fields--margins-small > div:nth-child(2) > div:nth-child(3) > div > div:nth-child(3) > div'
const indicatorLabelClass =
'#field-meta > div > div.render-fields.render-fields--margins-small > div:nth-child(2) > div:nth-child(3) > div > div:nth-child(2)'
const indicator = page.locator(indicatorClass)
const indicatorLabel = page.locator(indicatorLabelClass)
await expect(indicatorLabel).toContainText('23/50-60 chars, 27 to go')
await expect(indicator).toHaveCSS('background-color', 'rgb(255, 69, 0)')
})
test('Should generate a search result preview based on content', async () => {
await page.goto(url.edit(id))
const contentTabsClass = '.tabs-field__tabs .tabs-field__tab-button'
const autoGenerateButtonClass = '.group-field__wrap .render-fields div:nth-of-type(1) button'
const metaDescriptionClass = '#field-meta__description'
const previewClass =
'#field-meta > div > div.render-fields.render-fields--margins-small > div:nth-child(5)'
const secondTab = page.locator(contentTabsClass).nth(1)
await secondTab.click()
const metaDescription = page.locator(metaDescriptionClass)
await metaDescription.fill('My new amazing SEO description')
const preview = page.locator(previewClass)
await expect(preview).toContainText('https://yoursite.com/en/')
await expect(preview).toContainText('This is a test meta title')
await expect(preview).toContainText('My new amazing SEO description')
})
})
describe('i18n', () => {
test('support for another language', async () => {
await page.goto(url.edit(id))
const contentTabsClass = '.tabs-field__tabs .tabs-field__tab-button'
const autoGenerateButtonClass = '.group-field__wrap .render-fields div:nth-of-type(1) button'
const secondTab = page.locator(contentTabsClass).nth(1)
await secondTab.click()
const autoGenButton = page.locator(autoGenerateButtonClass).nth(0)
await expect(autoGenButton).toContainText('Auto-generate')
// Go to account page
await page.goto(url.account)
const languageField = page.locator('.payload-settings__language .react-select')
const options = page.locator('.rs__option')
// Change language to Spanish
await languageField.click()
await wait(200)
await options.locator('text=Español').click()
await expect(languageField).toContainText('Español')
await wait(600)
// Navigate back to the page
await page.goto(url.edit(id))
await wait(600)
await secondTab.click()
await wait(600)
await expect(autoGenButton).toContainText('Auto-génerar')
})
})
})