Files
openmaic/OpenMAIC/e2e/tests/slide-content-surface-647.spec.ts
2026-08-16 14:58:47 +08:00

88 lines
3.8 KiB
TypeScript

import { test, expect } from '../fixtures/base';
import { HomePage } from '../pages/home.page';
import { GenerationPreviewPage } from '../pages/generation-preview.page';
import { ClassroomPage } from '../pages/classroom.page';
import { createSettingsStorage } from '../fixtures/test-data/settings';
const SETTINGS_STORAGE = createSettingsStorage({ sidebarCollapsed: false });
/**
* PR3b — slide content surface completion (#647). Verifies the new
* surface-level affordances render and anchor correctly in Pro edit mode:
* the slide-background insert item, z-order on the element bar, and the
* image-type bar (replace/flip). Icon-class selectors keep the
* assertions locale-independent.
*/
test.describe('Slide content surface (#647)', () => {
test.beforeEach(async ({ page, mockApi }) => {
await page.addInitScript((settings) => {
localStorage.setItem('maic:account:settings-storage', settings);
}, SETTINGS_STORAGE);
await mockApi.setupGenerationMocks();
});
test('background, z-order, and image bar surface in Pro mode', async ({ page }, testInfo) => {
// Generate a classroom through the mocked pipeline, then enter Pro mode.
const home = new HomePage(page);
await home.goto();
// Dismiss the "What's New" changelog modal that overlays the home page on
// first load (it intercepts the submit button otherwise).
await page
.getByRole('button', { name: /got it|知道了/i })
.click({ timeout: 5_000 })
.catch(() => {});
await home.fillRequirement('讲解光合作用');
await home.enableInteractiveMode();
await home.submit();
await page.waitForURL(/\/generation-preview/);
const preview = new GenerationPreviewPage(page);
await preview.waitForRedirectToClassroom();
const classroom = new ClassroomPage(page);
await classroom.waitForLoaded();
await expect(classroom.sidebarScenes.first()).toBeVisible({ timeout: 10_000 });
await page.getByRole('switch').click();
await expect(page.getByTestId('slide-nav-rail')).toBeVisible({ timeout: 10_000 });
// --- Slide background: a PaintBucket insert item opens a solid/image popover.
const bgInsert = page.locator('button:has(.lucide-paint-bucket)');
// The insert toolbar may start collapsed — expand it if the item isn't shown.
if ((await bgInsert.count()) === 0) {
await page
.locator('button:has(.lucide-plus), button:has(.lucide-pencil-ruler)')
.first()
.click();
}
await expect(bgInsert).toBeVisible({ timeout: 10_000 });
await bgInsert.click();
// The background popover hosts the solid color picker (react-colorful).
await expect(page.locator('.color-picker, .react-colorful').first()).toBeVisible();
await testInfo.attach('slide-background-popover', {
body: await page.screenshot(),
contentType: 'image/png',
});
await page.keyboard.press('Escape');
// --- Z-order on the text element bar: select the title, expect to-front/to-back.
await page.locator('.editable-element-text').first().click();
await expect(page.locator('.lucide-bring-to-front').first()).toBeVisible({ timeout: 10_000 });
await expect(page.locator('.lucide-send-to-back').first()).toBeVisible();
await testInfo.attach('text-bar-zorder', {
body: await page.screenshot(),
contentType: 'image/png',
});
// --- Image insert popover hosts the picker (the image-type bar's
// replace/flip ops are covered by image-actions.test.ts and the
// image-flip round-trip suite, which don't need a live canvas).
await page.keyboard.press('Escape');
await page.locator('button:has(.lucide-image)').first().click();
await expect(page.getByPlaceholder(/https/i)).toBeVisible({ timeout: 10_000 });
await testInfo.attach('image-insert-popover', {
body: await page.screenshot(),
contentType: 'image/png',
});
});
});