diff --git a/tests/browser/result-navigation.spec.js b/tests/browser/result-navigation.spec.js index b0134db..7f55b43 100644 --- a/tests/browser/result-navigation.spec.js +++ b/tests/browser/result-navigation.spec.js @@ -31,3 +31,19 @@ test('opens Level A when Accessibility is already open', async ({ page }) => { await openAccessibilityResults(page); await expect(page.locator('#level-a')).toBeVisible(); }); + + +for (const detailed of [true, false]) { + test(`scan controls are reachable from ${detailed ? 'issue details' : 'the overview'}`, async ({ page }) => { + const { openPrepublishOverview } = await import('../live/result-view.mjs'); + await page.setContent(` + + +
Accessibility → Level A
+ `); + await openPrepublishOverview(page); + await expect(page.getByRole('button', { name: 'Recheck draft' })).toBeVisible(); + await expect(page.getByRole('button', { name: 'Back', exact: true })).toHaveCount(0); + }); +} diff --git a/tests/live/diagnostics.mjs b/tests/live/diagnostics.mjs index 4805d29..65928de 100644 --- a/tests/live/diagnostics.mjs +++ b/tests/live/diagnostics.mjs @@ -3,7 +3,8 @@ const flags = ['entitlementReady', 'pollSeen', 'pollOk', 'pollAuthenticated', 'p 'blockedExternalRequest', 'accessibilityCategoryVisible', 'imageIssuePresent', 'imageIssueVisible', 'resultAlertVisible', 'resultHasNestedFrame', 'resultRunning', 'resultRecheckVisible', 'prepublishViewSelected', 'livePageViewSelected', 'firstDraftImagePresent', - 'fixedDraftImagePresent', 'fixedDraftAlternativePresent']; + 'fixedDraftImagePresent', 'fixedDraftAlternativePresent', + 'firstIssueDetected', 'fixedDraftSaved', 'fixedIssueCleared']; // Only static SDK bundles; never application routes or query strings. export function publicSdkAsset(value) { diff --git a/tests/live/prepublish.spec.mjs b/tests/live/prepublish.spec.mjs index ad860d8..b128a81 100644 --- a/tests/live/prepublish.spec.mjs +++ b/tests/live/prepublish.spec.mjs @@ -2,7 +2,7 @@ import { test, expect } from '@playwright/test'; import { openLiveEditor } from './editor.mjs'; import { settings } from './settings.mjs'; import { observeDraft } from './prepublish.mjs'; -import { openAccessibilityResults, resultViewState } from './result-view.mjs'; +import { openAccessibilityResults, openPrepublishOverview, resultViewState } from './result-view.mjs'; import { publicSdkAsset } from './diagnostics.mjs'; import { imageAlternativeRule } from './accessibility-rule.mjs'; @@ -10,9 +10,8 @@ async function scan(page, evidence, marker) { const overlay = page.frameLocator('iframe.si-iframe-element'); const before = evidence[marker]; await test.step('live: start prepublish', async () => { - await overlay.getByRole('tab', { name: /Prepublish/i }) - .or(overlay.getByText('Prepublish view', { exact: true })).first().click(); - await overlay.getByRole('button', { name: /^(Run content check|Recheck draft)$/i }).click(); + await openPrepublishOverview(overlay); + await overlay.getByRole('button', { name: /^(Run content check|Recheck draft)$/i }).click({ timeout: 30_000 }); await expect(overlay.getByRole('button', { name: /Cancel content check/i })).toBeVisible(); }); await test.step('live: draft handoff', async () => { @@ -34,6 +33,7 @@ test('prepublish detects WCAG 1.1.1 image alternative issue and clears it after expect(Boolean(marker && fixedMarker && marker !== fixedMarker)).toBe(true); const evidence = await observeDraft(context, config.cmsOrigin, [marker, fixedMarker]); const sdkAssets = new Set(); + const progress = { firstIssueDetected: false, fixedDraftSaved: false, fixedIssueCleared: false }; page.on('response', response => { const asset = publicSdkAsset(response.url()); if (asset) sdkAssets.add(asset); @@ -56,6 +56,7 @@ test('prepublish detects WCAG 1.1.1 image alternative issue and clears it after await test.step('live: WCAG 1.1.1 issue detected', async () => { const overlay = page.frameLocator('iframe.si-iframe-element'); await expect(overlay.getByText(imageAlternativeRule.label, { exact: true })).toBeVisible(); + progress.firstIssueDetected = true; }); }); await test.step('saved draft correction is handed to the SDK and leaves the running state', async () => { @@ -65,6 +66,7 @@ test('prepublish detects WCAG 1.1.1 image alternative issue and clears it after await page.goto(`/episerver/cms/#context=epi.cms.contentdata:///${contentId}`); await expect(preview.locator('#live-test-marker')).toHaveText(fixedMarker); await expect(preview.locator('#live-test-image')).toHaveAttribute('alt', 'Blue square for the prepublish test'); + progress.fixedDraftSaved = true; const panel = page.locator('iframe.si-iframe-element'); if (!await panel.isVisible()) await page.locator('.si-smallbox button.si-button').click(); await expect(panel).toBeVisible(); @@ -78,11 +80,12 @@ test('prepublish detects WCAG 1.1.1 image alternative issue and clears it after await expect(overlay.getByText('Accessibility', { exact: true }).first()).toBeVisible(); await expect(overlay.getByRole('alert').filter({ visible: true })).toHaveCount(0); await expect(overlay.getByText(imageAlternativeRule.label, { exact: true })).toHaveCount(0); + progress.fixedIssueCleared = true; }); expect(await (await page.request.get(publishedPath)).text()).not.toContain(fixedMarker); }); } finally { - test.info().annotations.push({ type: 'live-diagnostics', description: JSON.stringify({ sdkAssets: [...sdkAssets], + test.info().annotations.push({ type: 'live-diagnostics', description: JSON.stringify({ ...progress, sdkAssets: [...sdkAssets], firstDraftImagePresent: evidence.captures[marker].imagePresent, fixedDraftImagePresent: evidence.captures[fixedMarker].imagePresent, fixedDraftAlternativePresent: evidence.captures[fixedMarker].fixedAlternativePresent }) }); diff --git a/tests/live/result-view.mjs b/tests/live/result-view.mjs index d5505ba..47fe6ff 100644 --- a/tests/live/result-view.mjs +++ b/tests/live/result-view.mjs @@ -24,6 +24,16 @@ export async function openAccessibilityResults(overlay) { && await level.getAttribute('aria-selected') !== 'true') await level.click(); } +export async function openPrepublishOverview(overlay) { + await overlay.getByRole('tab', { name: /Prepublish/i }) + .or(overlay.getByText('Prepublish view', { exact: true })).first().click({ timeout: 30_000 }); + // The SDK hides scan controls while a topic is selected. Its back action resets the overview. + const back = overlay.locator('[data-observe-key="navigation-button-back"]').filter({ visible: true }); + if (await back.count()) await back.click({ timeout: 30_000 }); + await expect(overlay.getByRole('button', { name: /^(Run content check|Recheck draft)$/i })) + .toBeVisible(); +} + export async function resultViewState(overlay) { const issue = overlay.getByText(imageAlternativeRule.label, { exact: true }); return {