fix: SEO SPA editor last fixes (3/4)

This commit is contained in:
Florian Sylvain committed 2026-10-16 16:31:17 +02:00
1 parent 470584400f
commit cb737b7ae3
19 files changed
+316 -147

No files matched your search

+103 -47
View File
@@ -5694,6 +5694,22 @@ async function seoSaveFromPanel(page: Page) {
.click()
}
const dismissColumnReason =
'The board draws a dismiss column and its footnote in the suggestion list; dismissal is deferred to slice 4'
const boardOmitsMobileDialogReason =
"The board's mobile frame omits the Create author dialog, so only the Details sheet is drawn"
function withMobileException<T extends VisualState>(state: T, mobile: number, reason: string): T {
return {
...state,
exception: {
maxPercent: { desktop: 10, mobile },
reason,
approvedBy: 'fsylvain',
},
}
}
const editorSeoStates: Record<string, VisualState> = {
'Collapsed: ready': seoSidebarState({}, false),
'Collapsed: suggestions': seoSidebarState(
@@ -5715,12 +5731,23 @@ const editorSeoStates: Record<string, VisualState> = {
true,
),
'Open: other site': seoSidebarState({ article: { site_id: 2 }, sites: [seoJournal()] }, true),
'Panel: defaults': seoPanelState({ check: seoCheck(['cover_none']) }),
'Panel: defaults': withMobileException(
seoPanelState({ check: seoCheck(['cover_none']) }),
26.5,
dismissColumnReason,
),
'Panel: filled in': seoPanelState({ article: seoFilled }),
'Panel: outside the soft ranges': seoPanelState({
article: { seo_title: seoLongTitle, seo_description: 'What a bathroom renovation costs.' },
check: seoCheck(['title_long', 'desc_short']),
}),
'Panel: outside the soft ranges': withMobileException(
seoPanelState({
article: {
seo_title: seoLongTitle,
seo_description: 'What a bathroom renovation costs.',
},
check: seoCheck(['title_long', 'desc_short']),
}),
15.5,
dismissColumnReason,
),
'Panel: slug edited': seoPanelState({ article: { slug: 'bathroom-costs' } }),
'Panel: slug taken': seoPanelState(
{
@@ -5738,20 +5765,28 @@ const editorSeoStates: Record<string, VisualState> = {
await page.getByText('is already used on Renew.').waitFor()
},
),
'Panel: cover without alt': seoPanelState({
article: seoCoverNoAlt,
check: seoCheck(['cover_alt']),
}),
'Panel: choose cover': seoPanelState({ check: seoCheck(['cover_none']) }, async (page) => {
await page
.getByRole('dialog')
.getByRole('button', { name: 'Choose image', exact: true })
.first()
.click()
await waitForPickerTiles(page)
await page.locator('[data-picker-tile][aria-label^="kitchen-after.webp,"]').click()
await page.mouse.move(0, 0)
}),
'Panel: cover without alt': withMobileException(
seoPanelState({
article: seoCoverNoAlt,
check: seoCheck(['cover_alt']),
}),
17,
dismissColumnReason,
),
'Panel: choose cover': withMobileException(
seoPanelState({ check: seoCheck(['cover_none']) }, async (page) => {
await page
.getByRole('dialog')
.getByRole('button', { name: 'Choose image', exact: true })
.first()
.click()
await waitForPickerTiles(page)
await page.locator('[data-picker-tile][aria-label^="kitchen-after.webp,"]').click()
await page.mouse.move(0, 0)
}),
29,
dismissColumnReason,
),
'Panel: social sharing open': seoPanelState(
{ article: { cover_image_id: 1, cover_image_alt: seoCoverAlt } },
(page) => seoOpenDisclosure(page, 'Social sharing'),
@@ -5778,12 +5813,19 @@ const editorSeoStates: Record<string, VisualState> = {
async () => {},
700,
),
'Panel: mobile search preview': seoPanelState(
{ article: { seo_title: seoLongTitle }, check: seoCheck(['title_long']) },
async (page) => {
await page.getByRole('dialog').getByRole('tab', { name: 'Mobile', exact: true }).click()
await page.mouse.move(0, 0)
},
'Panel: mobile search preview': withMobileException(
seoPanelState(
{ article: { seo_title: seoLongTitle }, check: seoCheck(['title_long']) },
async (page) => {
await page
.getByRole('dialog')
.getByRole('tab', { name: 'Mobile', exact: true })
.click()
await page.mouse.move(0, 0)
},
),
17.5,
dismissColumnReason,
),
'Panel: checking': seoPanelState({ check: { status: 200, hang: true } }),
'Panel: saving': seoPanelState(
@@ -6783,31 +6825,45 @@ export const visualStates: Record<string, Record<string, VisualState>> = {
{ authors: ['Inès Duarte', 'Jonas Pereira', 'Camille Roche'] },
(page) => liftAuthor(page, 'Camille Roche'),
),
'Create author: dialog': metaState({ withAuthor: true }, (page) =>
openCreateAuthorDialog(page, 'Zoe Lambert'),
'Create author: dialog': withMobileException(
metaState({ withAuthor: true }, (page) => openCreateAuthorDialog(page, 'Zoe Lambert')),
55,
boardOmitsMobileDialogReason,
),
'Create author: for me': metaState({}, async (page) => {
await openCreateAuthorDialog(page, 'Marta Alves')
await page.getByRole('checkbox', { name: /This is me/ }).click()
await page.mouse.move(0, 0)
}),
'Create author: slug taken': metaState(
{ withAuthor: true, overrides: { 'POST /v1/author/': newAuthorSlugTaken } },
async (page) => {
await openCreateAuthorDialog(page, 'Zoe Lambert')
await page.getByRole('button', { name: 'Create author', exact: true }).click()
await page.getByText('is already used by another author').waitFor()
'Create author: for me': withMobileException(
metaState({}, async (page) => {
await openCreateAuthorDialog(page, 'Marta Alves')
await page.getByRole('checkbox', { name: /This is me/ }).click()
await page.mouse.move(0, 0)
},
}),
50,
boardOmitsMobileDialogReason,
),
'Create author: failed': metaState(
{ withAuthor: true, overrides: { 'POST /v1/author/': { status: 500 } } },
async (page) => {
await openCreateAuthorDialog(page, 'Zoe Lambert')
await page.getByRole('button', { name: 'Create author', exact: true }).click()
await page.getByText("Couldn't create the author").waitFor()
await page.mouse.move(0, 0)
},
'Create author: slug taken': withMobileException(
metaState(
{ withAuthor: true, overrides: { 'POST /v1/author/': newAuthorSlugTaken } },
async (page) => {
await openCreateAuthorDialog(page, 'Zoe Lambert')
await page.getByRole('button', { name: 'Create author', exact: true }).click()
await page.getByText('is already used by another author').waitFor()
await page.mouse.move(0, 0)
},
),
40,
boardOmitsMobileDialogReason,
),
'Create author: failed': withMobileException(
metaState(
{ withAuthor: true, overrides: { 'POST /v1/author/': { status: 500 } } },
async (page) => {
await openCreateAuthorDialog(page, 'Zoe Lambert')
await page.getByRole('button', { name: 'Create author', exact: true }).click()
await page.getByText("Couldn't create the author").waitFor()
await page.mouse.move(0, 0)
},
),
52.5,
boardOmitsMobileDialogReason,
),
Loading: {
path: '/article/12/edit',