Rebuild the editor around one sidebar and play motion by default in 1.11.0
The editor follows the Flatsome UX Builder: dark top bar with the device switch, one sidebar with tabs for elements, structure and page, an element view with breadcrumbs, property tabs and actions, element cards, a context menu in the preview and keyboard shortcuts that also work inside the preview. Entrance and hover effects play for every visitor unless the website chooses to respect the browser's reduced-motion preference (setting "motion", class "motion-respect" on <html>). Waiting blocks stay hidden until they scroll into view and are shown at once when the reader jumps past them. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
ebc16777d6
commit
a1f8b905cd
18 files changed
+723
-433
No files matched your search
+61
-48
@@ -55,6 +55,10 @@ try {
|
||||
assert.deepEqual(result.violations.map(v => ({ id: v.id, nodes: v.nodes.map(n => n.target) })), [], name);
|
||||
checks.push({ name, violations: 0 });
|
||||
};
|
||||
const tab = name => page.getByRole('tab', { name, exact: true }).click();
|
||||
const treeSelect = async id => { await tab('Struktur'); await page.locator(`#structure [data-block-id="${id}"]`).click(); await page.locator(`#structure [data-edit-block="${id}"]`).click(); };
|
||||
const treeToggle = async id => { await tab('Struktur'); await page.locator(`#structure [data-toggle="${id}"]`).click(); };
|
||||
const addFromLibrary = async selector => { await tab('Elemente'); await page.locator(`#library ${selector}`).click(); };
|
||||
await page.goto(origin + '/admin');
|
||||
assert.equal(new URL(page.url()).pathname, '/admin/login');
|
||||
await axe('login');
|
||||
@@ -104,31 +108,22 @@ try {
|
||||
const frame = page.frameLocator('#preview');
|
||||
await frame.locator('h1').waitFor();
|
||||
await page.locator('#preview-status').filter({ hasText: 'Entwurf ·' }).waitFor();
|
||||
// Flexible panels, contextual fields and a root insertion from a deeply selected element.
|
||||
const leftHandle = page.locator('[data-resize="left"]'), rightHandle = page.locator('[data-resize="right"]');
|
||||
await leftHandle.focus(); await page.keyboard.press('ArrowRight');
|
||||
assert.equal(await leftHandle.getAttribute('aria-valuenow'), '290');
|
||||
const rightBox = await rightHandle.boundingBox();
|
||||
await page.mouse.move(rightBox.x + 3, rightBox.y + 100); await page.mouse.down();
|
||||
await page.mouse.move(rightBox.x - 57, rightBox.y + 100, { steps: 6 }); await page.mouse.up();
|
||||
assert.equal(await rightHandle.getAttribute('aria-valuenow'), '380');
|
||||
// One sidebar, contextual fields and a root insertion from a deeply selected element.
|
||||
await page.reload();
|
||||
await frame.locator('h1').waitFor();
|
||||
await page.locator('#preview-status').filter({ hasText: 'Entwurf ·' }).waitFor();
|
||||
assert.equal(await leftHandle.getAttribute('aria-valuenow'), '290');
|
||||
assert.equal(await rightHandle.getAttribute('aria-valuenow'), '380');
|
||||
for (const width of [1920, 1100, 850, 390]) {
|
||||
await page.setViewportSize({ width, height: 1100 });
|
||||
await page.waitForTimeout(100);
|
||||
assert.equal(await page.evaluate(() => document.documentElement.scrollWidth <= window.innerWidth), true, `workspace fits ${width}`);
|
||||
for (const selector of ['.left-panel', '.right-panel', '.library-buttons']) {
|
||||
for (const selector of ['.sidebar', '.sidebar-body', '.library-buttons']) {
|
||||
assert.equal(await page.locator(selector).first().evaluate(el => el.scrollWidth <= el.clientWidth + 1), true, `${selector} fits ${width}`);
|
||||
}
|
||||
}
|
||||
await page.setViewportSize({ width: 1600, height: 1100 });
|
||||
await frame.locator('h1').click();
|
||||
const sectionCount = await frame.locator('main > .block-section').count();
|
||||
await page.locator('#add-root-section').click();
|
||||
await addFromLibrary('[data-add="section"]');
|
||||
await page.waitForFunction(count => document.querySelector('#preview').contentDocument.querySelectorAll('main > .block-section').length === count + 1, sectionCount);
|
||||
await page.locator('#undo').click();
|
||||
await page.waitForFunction(count => document.querySelector('#preview').contentDocument.querySelectorAll('main > .block-section').length === count, sectionCount);
|
||||
@@ -136,7 +131,7 @@ try {
|
||||
await page.waitForFunction(count => document.querySelector('#preview').contentDocument.querySelectorAll('main > .block-section').length === count + 1, sectionCount);
|
||||
await page.locator('#undo').click();
|
||||
await frame.locator('h1').click();
|
||||
await page.locator('#library [data-add="image"]').click();
|
||||
await addFromLibrary('[data-add="image"]');
|
||||
await page.locator('[data-panel="design"]').click();
|
||||
assert.equal(await page.locator('#style-fontSize').count(), 0);
|
||||
assert.equal(await page.locator('#style-objectFit').isVisible(), true);
|
||||
@@ -169,17 +164,15 @@ try {
|
||||
await page.locator('#undo').click();
|
||||
await page.locator('#undo').click();
|
||||
await page.locator('#preview-status').filter({ hasText: 'Entwurf ·' }).waitFor();
|
||||
await page.locator('.right-panel').evaluate(el => el.scrollTop = 0);
|
||||
await page.locator('.left-panel > .panel-section').first().evaluate(el => el.scrollTop = 0);
|
||||
await page.locator('.sidebar-body').evaluate(el => el.scrollTop = 0);
|
||||
await page.screenshot({ path: 'reports/editor/flexible-workspace.png', fullPage: true });
|
||||
await leftHandle.dblclick(); await rightHandle.dblclick();
|
||||
await page.locator('[data-panel="content"]').click();
|
||||
checks.push({ name: 'resizable persistent panels, root sections, contextual image/text properties and full text width', passed: true });
|
||||
checks.push({ name: 'one sidebar, root sections, contextual image/text properties and full text width', passed: true });
|
||||
|
||||
// A layout starts empty: it must be visible, reachable and editable before it has any text.
|
||||
const previewReady = () => page.locator('#preview-status').filter({ hasText: 'Entwurf ·' }).waitFor();
|
||||
await frame.locator('h1').click();
|
||||
await page.locator('#add-root-section').click();
|
||||
await addFromLibrary('[data-add="section"]');
|
||||
await previewReady();
|
||||
const emptySection = frame.locator('main > .editor-empty-container');
|
||||
await emptySection.waitFor();
|
||||
@@ -197,10 +190,11 @@ try {
|
||||
assert.equal(await page.locator('#library-search').evaluate(el => el === document.activeElement), true);
|
||||
assert.match(await page.locator('#insert-hint').innerText(), /Spalte 2 von 2/);
|
||||
await page.locator('#library-search').fill('Text');
|
||||
await page.locator('#library [data-add="text"]').click();
|
||||
await addFromLibrary('[data-add="text"]');
|
||||
await frame.locator(`#${secondColumnId} .block-text`).waitFor();
|
||||
await previewReady();
|
||||
assert.equal(await frame.locator(`#${firstColumnId} .editor-empty`).count(), 1, 'unfilled sibling stays visible');
|
||||
await tab('Elemente');
|
||||
await page.locator('#library-search').fill('');
|
||||
const dragSource = page.locator('#library [data-add="button"]');
|
||||
await frame.locator(`#${firstColumnId} .editor-empty`).scrollIntoViewIfNeeded();
|
||||
@@ -249,6 +243,7 @@ try {
|
||||
const destination = frame.locator(`#${secondColumnId}`);
|
||||
await destination.scrollIntoViewIfNeeded();
|
||||
const box = await destination.boundingBox();
|
||||
await tab('Struktur');
|
||||
await page.locator(`#structure [data-block-id="${firstColumnId}"]`).dragTo(destination, {
|
||||
targetPosition: device === 'Desktop' ? { x: box.width - 8, y: 8 } : { x: 8, y: box.height - 8 },
|
||||
});
|
||||
@@ -268,7 +263,7 @@ try {
|
||||
assert.ok(publishedEmpty.includes(newSectionId));
|
||||
assert.equal(/editor-empty|data-editor-target|preview-containers|preview\.css|Inhalt hinzufügen/.test(publishedEmpty), false, 'public output has no editor aids');
|
||||
// Restore the fixture through the same editor actions; subsequent tests retain their baseline.
|
||||
await page.locator(`#structure [data-block-id="${newSectionId}"]`).click();
|
||||
await treeSelect(newSectionId);
|
||||
await page.locator('#delete').click();
|
||||
await page.locator('#save').click();
|
||||
await page.locator('#save-status').filter({ hasText: 'Entwurf gespeichert' }).waitFor();
|
||||
@@ -306,7 +301,7 @@ try {
|
||||
const headingId = await inPreview('h1');
|
||||
await page.getByRole('button', { name: 'Element dahinter einfügen', exact: true }).click();
|
||||
await page.locator('#insert-hint').waitFor({ state: 'visible' });
|
||||
await page.locator('#library button[data-add="text"]').click();
|
||||
await addFromLibrary('button[data-add="text"]');
|
||||
assert.equal(await page.locator('#properties-title').innerText(), 'Text');
|
||||
assert.equal(await page.locator('#insert-hint').isVisible(), false);
|
||||
await page.waitForFunction(id => {
|
||||
@@ -318,6 +313,7 @@ try {
|
||||
// Ziehen aus dem Werkzeugkasten auf die Seite.
|
||||
await frame.locator('h1').waitFor();
|
||||
const beforeButtons = await page.locator('#structure [data-block-id]').count();
|
||||
await tab('Elemente');
|
||||
await page.locator('#library button[data-add="button"]').dragTo(frame.locator('h1'), { targetPosition: { x: 12, y: 4 } });
|
||||
await page.waitForFunction(count => document.querySelectorAll('#structure [data-block-id]').length === count + 1, beforeButtons);
|
||||
assert.equal(await page.locator('#properties-title').innerText(), 'Button');
|
||||
@@ -351,15 +347,16 @@ try {
|
||||
// In einer Sektion wird die Zeile moeglich, die Spalte noch nicht. Die Sektion kommt aus dem
|
||||
// Strukturbaum, nicht aus der Vorschau: dort steht auch der Kopfbereich, und der gehoert
|
||||
// einem anderen Dokument.
|
||||
await tab('Struktur');
|
||||
await page.locator('#structure .tree-item').filter({ hasText: 'Sektion' }).first().click();
|
||||
assert.equal(await page.locator('#properties-title').innerText(), 'Sektion');
|
||||
assert.equal(await page.locator('#properties-title').textContent(), 'Sektion');
|
||||
assert.equal((await rowState()).disabled, false, 'Zeile in der Sektion moeglich');
|
||||
assert.equal((await toolboxState('column')).disabled, true, 'Spalte in der Sektion weiterhin gesperrt');
|
||||
|
||||
// Und in der Zeile wird die Spalte moeglich.
|
||||
const columnsBefore = await page.locator('#structure .tree-item').filter({ hasText: 'Spalte' }).count();
|
||||
await page.locator('#library button[data-row="3"]').click();
|
||||
assert.equal(await page.locator('#properties-title').innerText(), 'Zeile');
|
||||
await addFromLibrary('button[data-row="3"]');
|
||||
assert.equal(await page.locator('#properties-title').textContent(), 'Zeile');
|
||||
assert.equal((await toolboxState('column')).disabled, false, 'Spalte in der Zeile moeglich');
|
||||
assert.match((await toolboxState('column')).title, /Wird in Zeile eingefügt/);
|
||||
// Die Zeile bringt ihre drei Spalten mit. Die Testseite hat schon welche, also zaehlt die
|
||||
@@ -367,6 +364,7 @@ try {
|
||||
assert.equal(await page.locator('#structure .tree-item').filter({ hasText: 'Spalte' }).count(), columnsBefore + 3);
|
||||
await page.getByRole('button', { name: 'Rückgängig', exact: true }).click();
|
||||
// Jeder Eintrag traegt eine Zeichnung statt eines Schriftzeichens.
|
||||
await tab('Elemente');
|
||||
const mitBild = await page.locator('#library button .library-preview svg').count();
|
||||
const knoepfe = await page.locator('#library button').count();
|
||||
assert.equal(mitBild, knoepfe, `alle ${knoepfe} Eintraege haben ein Vorschaubild`);
|
||||
@@ -431,6 +429,7 @@ try {
|
||||
checks.push({ name: 'preview never shows unstyled content', passed: true });
|
||||
console.log('Preview edits and history passed.');
|
||||
|
||||
await tab('Struktur');
|
||||
await page.getByRole('button', { name: 'Einklappen', exact: true }).click();
|
||||
assert.equal(await page.locator('#structure .tree-item').count(), 3);
|
||||
await page.getByLabel('Element auf der Seite suchen', { exact: true }).fill('Meine bearbeitete');
|
||||
@@ -440,6 +439,8 @@ try {
|
||||
await page.getByLabel('Element auf der Seite suchen', { exact: true }).fill('');
|
||||
assert.equal(await page.locator('#structure [data-block-id="headline"]').isVisible(), true);
|
||||
await page.getByRole('button', { name: 'Alle öffnen', exact: true }).click();
|
||||
// Enter in the tree only selects; editing is the button next to the selected row.
|
||||
await page.locator('#structure [data-edit-block="headline"]').click();
|
||||
await page.getByRole('button', { name: 'Design', exact: true }).click();
|
||||
|
||||
const frameValue = async (selector, property, expected) => {
|
||||
@@ -495,7 +496,7 @@ try {
|
||||
assert.match(await contrast.textContent(), /Kontrast \d/, 'The panel reports a contrast ratio.');
|
||||
|
||||
// Per side spacing on the section, and a hover rule that also covers keyboard focus.
|
||||
await page.locator('#structure [data-block-id="hero"]').click();
|
||||
await treeSelect('hero');
|
||||
await page.getByRole('button', { name: 'Design', exact: true }).click();
|
||||
await setLength('style-padding-top', 96);
|
||||
await frameValue('#hero', 'paddingTop', '96px');
|
||||
@@ -539,7 +540,7 @@ try {
|
||||
await frameValue('#hero', 'paddingTop', '640px');
|
||||
|
||||
// Das Ziehfeld: seitwaerts ziehen aendert den Wert, und der ganze Zug ist ein Undo-Schritt.
|
||||
await page.locator('#structure [data-block-id="headline"]').click();
|
||||
await treeSelect('headline');
|
||||
await openGroup('Typografie');
|
||||
const scrub = page.locator('#style-fontSize');
|
||||
await scrub.scrollIntoViewIfNeeded();
|
||||
@@ -558,7 +559,7 @@ try {
|
||||
// Aufraeumen: dieser Abschnitt hat den Innenabstand des Hero auf 40rem an allen Seiten
|
||||
// gebracht. Das drueckt die Spaltenbreite auf null, und alles Folgende haette unsichtbare
|
||||
// Inhalte gepruef. Zurueck auf den Zustand von vorher: 96 px oben, sonst nichts.
|
||||
await page.locator('#structure [data-block-id="hero"]').click();
|
||||
await treeSelect('hero');
|
||||
await page.getByRole('button', { name: 'Design', exact: true }).click();
|
||||
await page.locator('#style-padding-unit').selectOption('px');
|
||||
for (const seite of ['right', 'bottom', 'left']) await setLength(`style-padding-${seite}`, '');
|
||||
@@ -587,6 +588,7 @@ try {
|
||||
});
|
||||
checks.push({ name: 'free styles: units, inheritance, single reset, palette colour, per-side spacing, hover rule', passed: true });
|
||||
|
||||
await tab('Elemente');
|
||||
await page.locator('[data-preset="columns"]').click();
|
||||
const presetSection = await page.locator('#structure .tree-item[aria-pressed="true"]').getAttribute('data-block-id');
|
||||
const presetRow = `#${presetSection} .block-row`;
|
||||
@@ -607,12 +609,12 @@ try {
|
||||
await frame.locator(presetRow).waitFor({ state: 'detached' });
|
||||
await page.getByRole('button', { name: 'Wiederholen', exact: true }).click();
|
||||
await columnCount(2);
|
||||
await page.locator('#structure [data-block-id="headline"]').click();
|
||||
await treeSelect('headline');
|
||||
await page.getByRole('button', { name: 'Inhalt', exact: true }).click();
|
||||
checks.push({ name: 'keyboard tree search and collapse, responsive inheritance/reset/undo, true viewport widths, spacing and responsive section preset', passed: true });
|
||||
console.log('Responsive design, tree tools and presets passed.');
|
||||
|
||||
await page.locator('#library [data-add="gallery"]').click();
|
||||
await addFromLibrary('[data-add="gallery"]');
|
||||
const galleryId = await page.locator('#structure .tree-item[aria-pressed="true"]').getAttribute('data-block-id');
|
||||
await page.getByRole('button', { name: 'Galeriebilder auswählen', exact: true }).click();
|
||||
await page.locator('#media-status').filter({ hasText: '0 Bilder' }).waitFor();
|
||||
@@ -639,12 +641,12 @@ try {
|
||||
await frame.locator(`#${galleryId} img`).first().scrollIntoViewIfNeeded();
|
||||
await page.waitForFunction(id => document.querySelector('#preview').contentDocument?.querySelector(`#${id} img`)?.naturalWidth > 0, galleryId);
|
||||
const imageId = await frame.locator(`#${galleryId} figure`).first().getAttribute('id');
|
||||
await page.locator(`#structure [data-block-id="${imageId}"]`).click();
|
||||
await treeSelect(imageId);
|
||||
await page.getByLabel('Bildunterschrift', { exact: true }).fill('Ein Ausblick zum Durchatmen.');
|
||||
await frame.getByText('Ein Ausblick zum Durchatmen.', { exact: true }).waitFor();
|
||||
await page.getByRole('button', { name: 'Nach unten verschieben', exact: true }).click();
|
||||
await page.getByRole('button', { name: 'Rückgängig', exact: true }).click();
|
||||
await page.locator(`#structure [data-block-id="${galleryId}"]`).click();
|
||||
await treeSelect(galleryId);
|
||||
await page.getByRole('button', { name: 'Design', exact: true }).click();
|
||||
await openGroup('Layout');
|
||||
await page.locator('#style-gridColumns').fill('2');
|
||||
@@ -661,7 +663,7 @@ try {
|
||||
await openGroup('Bewegung und Effekte');
|
||||
await page.getByLabel('Schatten', { exact: true }).selectOption('soft');
|
||||
await page.getByLabel('Hover-Effekt', { exact: true }).selectOption('lift');
|
||||
for (const [effect, transform] of [['left', 'translateX(-36px)'], ['right', 'translateX(36px)']]) {
|
||||
for (const [effect, transform] of [['left', 'translateX(-56px)'], ['right', 'translateX(56px)']]) {
|
||||
await page.getByLabel('Einblendung beim Erscheinen', { exact: true }).selectOption(effect);
|
||||
await frame.locator(`#${galleryId}.fx-entrance-${effect}`).waitFor();
|
||||
await page.locator('#preview-status').filter({ hasText: 'Entwurf ·' }).waitFor();
|
||||
@@ -672,19 +674,31 @@ try {
|
||||
element.animate = (frames, options) => { window.observedEntrance.push(frames); return animate(frames, options); };
|
||||
element.scrollIntoView();
|
||||
}, galleryId);
|
||||
await page.getByRole('button', { name: 'Bewegung testen', exact: true }).click();
|
||||
await page.getByRole('button', { name: 'Bewegung in der Vorschau abspielen', exact: true }).click();
|
||||
await page.waitForFunction(() => window.observedEntrance.length > 0);
|
||||
assert.equal(await page.evaluate(() => window.observedEntrance[0][0].transform), transform);
|
||||
await page.getByRole('button', { name: 'Bewegung stoppen', exact: true }).click();
|
||||
await page.getByRole('button', { name: 'Bewegung in der Vorschau stoppen', exact: true }).click();
|
||||
}
|
||||
// Default setting: the preview plays even when the browser asks for less motion (Flatsome mode).
|
||||
await page.emulateMedia({ reducedMotion: 'reduce' });
|
||||
await page.evaluate(() => { window.observedEntrance = []; });
|
||||
await page.getByRole('button', { name: 'Bewegung testen', exact: true }).click();
|
||||
await page.waitForTimeout(800);
|
||||
assert.equal(await page.evaluate(() => window.observedEntrance.length), 0, 'reduced motion suppresses entrance playback');
|
||||
await page.getByRole('button', { name: 'Bewegung stoppen', exact: true }).click();
|
||||
await page.getByRole('button', { name: 'Bewegung in der Vorschau abspielen', exact: true }).click();
|
||||
await page.waitForFunction(() => window.observedEntrance.length > 0);
|
||||
assert.equal(await page.locator('#motion-status').isVisible(), false, 'no motion note while the site ignores the preference');
|
||||
await page.getByRole('button', { name: 'Bewegung in der Vorschau stoppen', exact: true }).click();
|
||||
// Setting "Browservorgabe beachten", as the preview would carry it: nothing plays, the note shows.
|
||||
await page.evaluate(() => { document.querySelector('#preview').contentDocument.documentElement.classList.add('motion-respect'); window.observedEntrance = []; });
|
||||
await page.emulateMedia({ reducedMotion: 'no-preference' });
|
||||
checks.push({ name: 'distinct left/right entrance playback and reduced motion in the sandbox', passed: true });
|
||||
await page.waitForTimeout(200);
|
||||
await page.emulateMedia({ reducedMotion: 'reduce' });
|
||||
await page.locator('#motion-status').waitFor({ state: 'visible' });
|
||||
await page.getByRole('button', { name: 'Bewegung in der Vorschau abspielen', exact: true }).click();
|
||||
await page.waitForTimeout(800);
|
||||
assert.equal(await page.evaluate(() => window.observedEntrance.length), 0, 'reduced motion suppresses entrance playback when respected');
|
||||
await page.getByRole('button', { name: 'Bewegung in der Vorschau stoppen', exact: true }).click();
|
||||
await page.emulateMedia({ reducedMotion: 'no-preference' });
|
||||
await page.locator('#motion-status').waitFor({ state: 'hidden' });
|
||||
checks.push({ name: 'distinct left/right entrance playback, Flatsome-mode playback and respected reduced motion in the sandbox', passed: true });
|
||||
await page.getByLabel('Einblendung beim Erscheinen', { exact: true }).selectOption('rise');
|
||||
await frame.locator(`#${galleryId}.fx-entrance-rise`).waitFor();
|
||||
await page.getByRole('button', { name: 'Mobil', exact: true }).click();
|
||||
@@ -698,7 +712,7 @@ try {
|
||||
await frameValue(`#${galleryId}`, 'animationName', 'none');
|
||||
await frameValue(`#${galleryId}`, 'transform', 'none');
|
||||
await page.emulateMedia({ reducedMotion: 'no-preference' });
|
||||
await page.locator('#open-media-library').click();
|
||||
await (await tab('Elemente'), page.locator('#open-media-library').click());
|
||||
await page.locator('#media-status').filter({ hasText: '2 Bilder' }).waitFor();
|
||||
await page.locator(`[data-media-id="${mediaItems[0].id}"]`).click();
|
||||
await page.getByRole('button', { name: 'Archivieren', exact: true }).click();
|
||||
@@ -709,25 +723,23 @@ try {
|
||||
await page.getByRole('button', { name: 'Wiederherstellen', exact: true }).click();
|
||||
await page.locator('#media-status').filter({ hasText: '2 Bilder' }).waitFor();
|
||||
await page.getByRole('button', { name: 'Schließen', exact: true }).click();
|
||||
await page.locator('#structure [data-block-id="headline"]').click();
|
||||
await treeSelect('headline');
|
||||
await page.getByRole('button', { name: 'Inhalt', exact: true }).click();
|
||||
checks.push({ name: 'image upload, alt metadata, multi-select gallery, caption, sorting undo, archive/restore, responsive variants and reduced-motion effects', passed: true });
|
||||
console.log('Media library, gallery and effects passed.');
|
||||
|
||||
await page.locator('#library [data-add="text"]').click();
|
||||
await addFromLibrary('[data-add="text"]');
|
||||
await page.getByLabel('Text', { exact: true }).fill('Dieser Absatz wurde im Editor eingefügt.');
|
||||
await page.getByRole('button', { name: 'Duplizieren', exact: true }).click();
|
||||
await page.getByLabel('Text', { exact: true }).fill('Das ist eine unabhängige Kopie.');
|
||||
await page.getByRole('button', { name: 'Nach oben verschieben', exact: true }).click();
|
||||
await page.getByRole('button', { name: 'Löschen', exact: true }).click();
|
||||
await page.getByRole('button', { name: 'Rückgängig', exact: true }).click();
|
||||
await page.locator('#toggle-library').click();
|
||||
await page.locator(`#structure [data-toggle="${presetSection}"]`).click();
|
||||
await page.locator(`#structure [data-toggle="${galleryId}"]`).click();
|
||||
await treeToggle(presetSection);
|
||||
await treeToggle(galleryId);
|
||||
await page.getByRole('button', { name: 'Text: Dieser Absatz wurde im Editor eingefügt.', exact: true }).dragTo(page.locator('#structure [data-block-id="principles"]'));
|
||||
await page.waitForFunction(() => document.querySelector('#structure [data-block-id="principles"]')?.parentElement.textContent.includes('Dieser Absatz wurde im Editor eingefügt.'));
|
||||
await page.getByRole('button', { name: 'Rückgängig', exact: true }).click();
|
||||
await page.locator('#toggle-library').click();
|
||||
await page.route('**/admin/api/pages/test-home/draft', route => route.abort(), { times: 1 });
|
||||
await page.getByRole('button', { name: 'Entwurf speichern', exact: true }).click();
|
||||
await page.locator('#message').filter({ hasText: 'Verbindung ist unterbrochen' }).waitFor();
|
||||
@@ -881,8 +893,9 @@ try {
|
||||
// Back into the editor. The draft differs from the published state by now, so wait for the
|
||||
// structure rather than for a particular save status.
|
||||
await page.goto(origin + '/admin/pages/test-home');
|
||||
await tab('Struktur');
|
||||
await page.locator('#structure [data-block-id="headline"]').waitFor();
|
||||
await page.locator('#structure [data-block-id="headline"]').click();
|
||||
await treeSelect('headline');
|
||||
await page.getByRole('button', { name: 'Design', exact: true }).click();
|
||||
await page.locator('#preview-status').filter({ hasText: 'Entwurf ·' }).waitFor();
|
||||
await axe('desktop editor');
|
||||
@@ -894,7 +907,7 @@ try {
|
||||
assert.equal(await page.evaluate(() => document.documentElement.scrollWidth <= innerWidth), true);
|
||||
await axe('mobile editor');
|
||||
await page.screenshot({ path: 'reports/editor/editor-phone.png', fullPage: true });
|
||||
await page.locator('#open-media-library').click();
|
||||
await (await tab('Elemente'), page.locator('#open-media-library').click());
|
||||
await page.locator('#media-status').filter({ hasText: '2 Bilder' }).waitFor();
|
||||
await axe('mobile media library');
|
||||
await page.screenshot({ path: 'reports/editor/media-phone.png', fullPage: true });
|
||||
|
||||
Reference in new issue
Block a user