fix: locale switcher flakey test (#5761)

This commit is contained in:
Jarrod Flesch
2024-04-10 13:05:30 -04:00
committed by GitHub
parent 14498e8a9c
commit 2deeb61f17
5 changed files with 52 additions and 65 deletions

View File

@@ -430,7 +430,7 @@ describe('admin', () => {
const { id } = await createPost() const { id } = await createPost()
await page.goto(postsUrl.edit(id)) await page.goto(postsUrl.edit(id))
await page.locator('#field-title')?.fill('') await page.locator('#field-title')?.fill('')
expect(await page.locator('.doc-header__title.render-title')?.innerText()).toContain('ID:') await expect(page.locator('.doc-header__title.render-title:has-text("ID:")')).toBeVisible()
await saveDocAndAssert(page) await saveDocAndAssert(page)
}) })

View File

@@ -11,7 +11,9 @@ import type { Config } from './payload-types.js'
import { import {
ensureAutoLoginAndCompilationIsDone, ensureAutoLoginAndCompilationIsDone,
initPageConsoleErrorCatch, initPageConsoleErrorCatch,
navigateToListCellLink,
saveDocAndAssert, saveDocAndAssert,
switchTab,
} from '../helpers.js' } from '../helpers.js'
import { AdminUrlUtil } from '../helpers/adminUrlUtil.js' import { AdminUrlUtil } from '../helpers/adminUrlUtil.js'
import { initPayloadE2ENoConfig } from '../helpers/initPayloadE2ENoConfig.js' import { initPayloadE2ENoConfig } from '../helpers/initPayloadE2ENoConfig.js'
@@ -34,11 +36,7 @@ let serverURL: string
// If we want to make this run in parallel: test.describe.configure({ mode: 'parallel' }) // If we want to make this run in parallel: test.describe.configure({ mode: 'parallel' })
describe('fields', () => { describe('fields', () => {
beforeAll(async ({ browser }, testInfo) => { beforeAll(async ({ browser }) => {
// const prebuild = Boolean(process.env.CI)
// if (prebuild) testInfo.setTimeout(testInfo.timeout * 3)
process.env.SEED_IN_CONFIG_ONINIT = 'false' // Makes it so the payload config onInit seed is not run. Otherwise, the seed would be run unnecessarily twice for the initial test run - once for beforeEach and once for onInit process.env.SEED_IN_CONFIG_ONINIT = 'false' // Makes it so the payload config onInit seed is not run. Otherwise, the seed would be run unnecessarily twice for the initial test run - once for beforeEach and once for onInit
;({ payload, serverURL } = await initPayloadE2ENoConfig({ ;({ payload, serverURL } = await initPayloadE2ENoConfig({
dirname, dirname,
@@ -542,20 +540,17 @@ describe('fields', () => {
const jsonValue = '{ "foo": "bar"}' const jsonValue = '{ "foo": "bar"}'
await page.goto(url.create) await page.goto(url.create)
await page.waitForURL(url.create)
await wait(1000) await switchTab(page, '.tabs-field__tab-button:has-text("Tab with Row")')
await page.locator('.tabs-field__tab-button:has-text("Tab with Row")').click()
await page.locator('#field-textInRow').fill(textInRowValue) await page.locator('#field-textInRow').fill(textInRowValue)
await page.locator('#field-numberInRow').fill(numberInRowValue) await page.locator('#field-numberInRow').fill(numberInRowValue)
await page.locator('.json-field .inputarea').fill(jsonValue) await page.locator('.json-field .inputarea').fill(jsonValue)
await wait(300) await wait(300)
await page.locator('.tabs-field__tab-button:has-text("Tab with Array")').click() await switchTab(page, '.tabs-field__tab-button:has-text("Tab with Array")')
await page.locator('.tabs-field__tab-button:has-text("Tab with Row")').click() await switchTab(page, '.tabs-field__tab-button:has-text("Tab with Row")')
await wait(100)
await expect(page.locator('#field-textInRow')).toHaveValue(textInRowValue) await expect(page.locator('#field-textInRow')).toHaveValue(textInRowValue)
await expect(page.locator('#field-numberInRow')).toHaveValue(numberInRowValue) await expect(page.locator('#field-numberInRow')).toHaveValue(numberInRowValue)
@@ -566,46 +561,43 @@ describe('fields', () => {
const textInRowValue = 'new value' const textInRowValue = 'new value'
const jsonValue = '{ "new": "value"}' const jsonValue = '{ "new": "value"}'
await page.goto(url.list) await page.goto(url.list)
await page.locator('.cell-id a').click() await navigateToListCellLink(page)
await wait(500)
// Go to Row tab, update the value // Go to Row tab, update the value
await page.locator('.tabs-field__tab-button:has-text("Tab with Row")').click() await switchTab(page, '.tabs-field__tab-button:has-text("Tab with Row")')
await page.locator('#field-textInRow').fill(textInRowValue) await page.locator('#field-textInRow').fill(textInRowValue)
await page.locator('.json-field .inputarea').fill(jsonValue) await page.locator('.json-field .inputarea').fill(jsonValue)
await wait(500) await wait(500)
// Go to Array tab, then back to Row. Make sure new value is still there // Go to Array tab, then back to Row. Make sure new value is still there
await page.locator('.tabs-field__tab-button:has-text("Tab with Array")').click() await switchTab(page, '.tabs-field__tab-button:has-text("Tab with Array")')
await page.locator('.tabs-field__tab-button:has-text("Tab with Row")').click() await switchTab(page, '.tabs-field__tab-button:has-text("Tab with Row")')
await expect(page.locator('#field-textInRow')).toHaveValue(textInRowValue) await expect(page.locator('#field-textInRow')).toHaveValue(textInRowValue)
await expect(page.locator('.json-field .lines-content')).toContainText(jsonValue) await expect(page.locator('.json-field .lines-content')).toContainText(jsonValue)
// Go to array tab, save the doc // Go to array tab, save the doc
await page.locator('.tabs-field__tab-button:has-text("Tab with Array")').click() await switchTab(page, '.tabs-field__tab-button:has-text("Tab with Array")')
await page.click('#action-save', { delay: 100 }) await saveDocAndAssert(page)
await wait(500)
// Go back to row tab, make sure the new value is still present // Go back to row tab, make sure the new value is still present
await page.locator('.tabs-field__tab-button:has-text("Tab with Row")').click() await switchTab(page, '.tabs-field__tab-button:has-text("Tab with Row")')
await expect(page.locator('#field-textInRow')).toHaveValue(textInRowValue) await expect(page.locator('#field-textInRow')).toHaveValue(textInRowValue)
}) })
test('should render array data within unnamed tabs', async () => { test('should render array data within unnamed tabs', async () => {
await page.goto(url.list) await page.goto(url.list)
await page.locator('.cell-id a').click() await navigateToListCellLink(page)
await page.locator('.tabs-field__tab-button:has-text("Tab with Array")').click() await switchTab(page, '.tabs-field__tab-button:has-text("Tab with Array")')
await expect(page.locator('#field-array__0__text')).toHaveValue("Hello, I'm the first row") await expect(page.locator('#field-array__0__text')).toHaveValue("Hello, I'm the first row")
}) })
test('should render array data within named tabs', async () => { test('should render array data within named tabs', async () => {
await page.goto(url.list) await page.goto(url.list)
await page.locator('.cell-id a').click() await navigateToListCellLink(page)
await page.locator('.tabs-field__tab-button:nth-child(5)').click() await switchTab(page, '.tabs-field__tab-button:nth-child(5)')
await expect(page.locator('#field-tab__array__0__text')).toHaveValue( await expect(page.locator('#field-tab__array__0__text')).toHaveValue(
"Hello, I'm the first row, in a named tab", "Hello, I'm the first row, in a named tab",
) )

View File

@@ -141,11 +141,10 @@ export async function openDocControls(page: Page): Promise<void> {
await expect(page.locator('.doc-controls__popup >> .popup__content')).toBeVisible() await expect(page.locator('.doc-controls__popup >> .popup__content')).toBeVisible()
} }
export async function changeLocale(page: Page, newLocale: string, skipURLCheck: boolean = false) { export async function changeLocale(page: Page, newLocale: string) {
await page.locator('.localizer >> button').first().click() await page.locator('.localizer >> button').first().click()
await page await page
.locator(`.localizer`) .locator(`.localizer .popup.popup--active .popup-button-list button`, {
.locator(`.popup >> button`, {
hasText: newLocale, hasText: newLocale,
}) })
.first() .first()
@@ -153,11 +152,7 @@ export async function changeLocale(page: Page, newLocale: string, skipURLCheck:
const regexPattern = new RegExp(`locale=${newLocale}`) const regexPattern = new RegExp(`locale=${newLocale}`)
if (skipURLCheck) { await expect(page).toHaveURL(regexPattern)
await wait(500)
} else {
await expect(page).toHaveURL(regexPattern)
}
} }
export function exactText(text: string) { export function exactText(text: string) {
@@ -196,12 +191,25 @@ export const findTableCell = (page: Page, fieldName: string, rowTitle?: string):
return cell return cell
} }
export async function navigateToListCellLink(page: Page, selector = '.cell-id') {
const cellLink = page.locator(`${selector} a`).first()
const linkURL = await cellLink.getAttribute('href')
await cellLink.click()
await page.waitForURL(`**${linkURL}`)
}
export const findTableRow = (page: Page, title: string): Locator => { export const findTableRow = (page: Page, title: string): Locator => {
const row = page.locator(`tbody tr:has-text("${title}")`) const row = page.locator(`tbody tr:has-text("${title}")`)
expect(row).toBeTruthy() expect(row).toBeTruthy()
return row return row
} }
export async function switchTab(page: Page, selector: string) {
await page.locator(selector).click()
await wait(300)
await expect(page.locator(`${selector}.tabs-field__tab-button--active`)).toBeVisible()
}
/** /**
* Throws an error when browser console error messages (with some exceptions) are thrown, thus resulting * Throws an error when browser console error messages (with some exceptions) are thrown, thus resulting
* in the e2e test failing. * in the e2e test failing.

View File

@@ -8,6 +8,7 @@ import {
ensureAutoLoginAndCompilationIsDone, ensureAutoLoginAndCompilationIsDone,
exactText, exactText,
initPageConsoleErrorCatch, initPageConsoleErrorCatch,
navigateToListCellLink,
saveDocAndAssert, saveDocAndAssert,
} from '../helpers.js' } from '../helpers.js'
import { AdminUrlUtil } from '../helpers/adminUrlUtil.js' import { AdminUrlUtil } from '../helpers/adminUrlUtil.js'
@@ -26,25 +27,21 @@ describe('Live Preview', () => {
const goToDoc = async (page: Page) => { const goToDoc = async (page: Page) => {
await page.goto(url.list) await page.goto(url.list)
const linkToDoc = page.locator('tbody tr:first-child .cell-id a').first() await page.waitForURL(url.list)
await navigateToListCellLink(page)
await expect(() => expect(linkToDoc).toBeTruthy()).toPass({ timeout: POLL_TOPASS_TIMEOUT })
const linkDocHref = await linkToDoc.getAttribute('href')
await linkToDoc.click()
await page.waitForURL(`**${linkDocHref}`)
} }
const goToCollectionPreview = async (page: Page): Promise<void> => { const goToCollectionPreview = async (page: Page): Promise<void> => {
await goToDoc(page) await goToDoc(page)
await page.goto(`${page.url()}/preview`) await page.goto(`${page.url()}/preview`)
await page.waitForURL(`**/preview`)
} }
const goToGlobalPreview = async (page: Page, slug: string): Promise<void> => { const goToGlobalPreview = async (page: Page, slug: string): Promise<void> => {
const global = new AdminUrlUtil(serverURL, slug) const global = new AdminUrlUtil(serverURL, slug)
const previewURL = `${global.global(slug)}/preview` const previewURL = `${global.global(slug)}/preview`
await page.goto(previewURL) await page.goto(previewURL)
await page.waitForURL(previewURL)
} }
beforeAll(async ({ browser }) => { beforeAll(async ({ browser }) => {
@@ -78,12 +75,9 @@ describe('Live Preview', () => {
test('collection — has route', async () => { test('collection — has route', async () => {
await goToDoc(page) await goToDoc(page)
const url = page.url()
await goToCollectionPreview(page) await goToCollectionPreview(page)
await expect(() => expect(page.url()).toBe(`${url}/preview`)).toPass({ await expect(page.locator('.live-preview')).toBeVisible()
timeout: POLL_TOPASS_TIMEOUT,
})
}) })
test('collection — renders iframe', async () => { test('collection — renders iframe', async () => {
@@ -127,6 +121,7 @@ describe('Live Preview', () => {
test('global — has tab', async () => { test('global — has tab', async () => {
const global = new AdminUrlUtil(serverURL, 'header') const global = new AdminUrlUtil(serverURL, 'header')
await page.goto(global.global('header')) await page.goto(global.global('header'))
await page.waitForURL(global.global('header'))
const docURL = page.url() const docURL = page.url()
const pathname = new URL(docURL).pathname const pathname = new URL(docURL).pathname
@@ -169,17 +164,13 @@ describe('Live Preview', () => {
test('properly measures iframe and displays size', async () => { test('properly measures iframe and displays size', async () => {
await page.goto(url.create) await page.goto(url.create)
await page.waitForURL(url.create)
await page.locator('#field-title').fill('Title 3') await page.locator('#field-title').fill('Title 3')
await page.locator('#field-slug').fill('slug-3') await page.locator('#field-slug').fill('slug-3')
await saveDocAndAssert(page) await saveDocAndAssert(page)
await goToCollectionPreview(page) await goToCollectionPreview(page)
await expect(() => expect(page.url()).toContain('/preview')).toPass({
timeout: POLL_TOPASS_TIMEOUT,
})
const iframe = page.locator('iframe') const iframe = page.locator('iframe')
// Measure the actual iframe size and compare it with the inputs rendered in the toolbar // Measure the actual iframe size and compare it with the inputs rendered in the toolbar
@@ -222,17 +213,13 @@ describe('Live Preview', () => {
test('resizes iframe to specified breakpoint', async () => { test('resizes iframe to specified breakpoint', async () => {
await page.goto(url.create) await page.goto(url.create)
await expect.poll(() => page.url(), { timeout: POLL_TOPASS_TIMEOUT }).toContain('create') await page.waitForURL(url.create)
await page.locator('#field-title').fill('Title 4') await page.locator('#field-title').fill('Title 4')
await page.locator('#field-slug').fill('slug-4') await page.locator('#field-slug').fill('slug-4')
await saveDocAndAssert(page) await saveDocAndAssert(page)
await goToCollectionPreview(page) await goToCollectionPreview(page)
await expect(() => expect(page.url()).toContain('/preview')).toPass({
timeout: POLL_TOPASS_TIMEOUT,
})
// Check that the breakpoint select is present // Check that the breakpoint select is present
const breakpointSelector = page.locator( const breakpointSelector = page.locator(
'.live-preview-toolbar-controls__breakpoint button.popup-button', '.live-preview-toolbar-controls__breakpoint button.popup-button',

View File

@@ -86,7 +86,7 @@ describe('Localization', () => {
await fillValues({ description, title: spanishTitle }) await fillValues({ description, title: spanishTitle })
await saveDocAndAssert(page) await saveDocAndAssert(page)
await changeLocale(page, defaultLocale, true) await changeLocale(page, defaultLocale)
// Expect english title // Expect english title
await expect(page.locator('#field-title')).toHaveValue(title) await expect(page.locator('#field-title')).toHaveValue(title)
@@ -105,7 +105,7 @@ describe('Localization', () => {
await saveDocAndAssert(page) await saveDocAndAssert(page)
// Change back to English // Change back to English
await changeLocale(page, defaultLocale, true) await changeLocale(page, defaultLocale)
// Localized field should not be populated // Localized field should not be populated
await expect(page.locator('#field-title')).toBeEmpty() await expect(page.locator('#field-title')).toBeEmpty()
@@ -133,7 +133,7 @@ describe('Localization', () => {
await saveDocAndAssert(page) await saveDocAndAssert(page)
// Change back to English // Change back to English
await changeLocale(page, defaultLocale, true) await changeLocale(page, defaultLocale)
// Localized field should not be populated // Localized field should not be populated
await expect(page.locator('#field-title')).toBeEmpty() await expect(page.locator('#field-title')).toBeEmpty()
@@ -191,9 +191,9 @@ describe('Localization', () => {
test('should duplicate localized checkbox correctly', async () => { test('should duplicate localized checkbox correctly', async () => {
await page.goto(url.create) await page.goto(url.create)
await page.waitForURL(`**${url.create}`) await page.waitForURL(url.create)
//await changeLocale(page, defaultLocale, true) await changeLocale(page, defaultLocale)
await fillValues({ description, title: englishTitle }) await fillValues({ description, title: englishTitle })
await page.locator('#field-localizedCheckbox').click() await page.locator('#field-localizedCheckbox').click()
@@ -207,7 +207,7 @@ describe('Localization', () => {
await expect(page.locator('#field-localizedCheckbox')).not.toBeChecked() await expect(page.locator('#field-localizedCheckbox')).not.toBeChecked()
// duplicate doc // duplicate doc
await changeLocale(page, defaultLocale, true) await changeLocale(page, defaultLocale)
await openDocControls(page) await openDocControls(page)
await page.locator('#action-duplicate').click() await page.locator('#action-duplicate').click()
@@ -225,7 +225,7 @@ describe('Localization', () => {
test('should duplicate even if missing some localized data', async () => { test('should duplicate even if missing some localized data', async () => {
// create a localized required doc // create a localized required doc
await page.goto(urlWithRequiredLocalizedFields.create) await page.goto(urlWithRequiredLocalizedFields.create)
await changeLocale(page, defaultLocale, true) await changeLocale(page, defaultLocale)
await page.locator('#field-title').fill(englishTitle) await page.locator('#field-title').fill(englishTitle)
await page.locator('#field-layout .blocks-field__drawer-toggler').click() await page.locator('#field-layout .blocks-field__drawer-toggler').click()
await page.locator('button[title="Text"]').click() await page.locator('button[title="Text"]').click()