import { test, expect, Page } from '@playwright/test'; import { setApiKeyViaUI, createNewView, configureViewSettings, applyThemeToView, waitForStoryCells, measureStoryCells, } from './helpers/demo-ui-helpers'; /** * E2E test for round tile growth bug (ST-18400) using the demo site UI * This test properly interacts with the demo site to create views and test the bug fix */ test.describe('Round Tile Growth Bug - Demo Site UI', () => { let page: Page; // Test configuration with real API key and category const TEST_API_KEY = 'addc0a74-97dd-4a42-8b0e-eac055df8b84'; const TEST_CATEGORY = 'manual1'; test.beforeEach(async ({ page: testPage }) => { page = testPage; // Navigate to demo site await page.goto('http://localhost:8080'); // Wait for demo to load await page.waitForSelector('.demo', { timeout: 30000 }); // Set API key via the Settings UI await setApiKeyViaUI(page, TEST_API_KEY); // Wait for any existing views to render await page.waitForTimeout(2000); }); test('round tiles should not grow infinitely when title.show = false', async () => { console.log('Starting test: Round tiles without titles'); // Step 1: Create a new view let viewIndex: number; await test.step('Create new view', async () => { viewIndex = await createNewView(page); }); // Step 2: Configure the view for Stories with Round tiles and set category await test.step('Configure view settings and category', async () => { // Configure view settings and category in one operation await configureViewSettings(page, viewIndex, { mediaType: 'stories', viewType: 'row', tileType: 'round', category: TEST_CATEGORY, }); }); // Step 3: Configure theme to hide titles await test.step('Configure theme to hide titles', async () => { // Create theme JSON with hidden titles (this triggers the bug in unfixed version) const themeWithHiddenTitles = { storyTiles: { title: { show: false, // This is what triggers the bug }, circularTile: { readStrokeWidth: 2, unreadStrokeWidth: 3, }, }, lists: { row: { tileSpacing: 8, startInset: 16, endInset: 16, }, }, }; await applyThemeToView(page, viewIndex, themeWithHiddenTitles); }); // Step 4: Wait for stories to load and measure the round cells await test.step('Monitor cell sizes for growth', async () => { // Give time for SDK to initialize and load stories await page.waitForTimeout(3000); // Wait for actual story cells to load (use a shorter timeout) const cellCount = await waitForStoryCells(page, 5000); // If no cells loaded, just skip the growth monitoring if (cellCount === 0) { console.log('No story cells loaded, skipping growth check'); return; } // Get initial measurements const initialMeasurements = await measureStoryCells(page); console.log('Initial measurements:', initialMeasurements); // If we have measurements, monitor for growth if (initialMeasurements) { const sizeHistory = []; // Monitor size changes over 3 seconds for (let i = 0; i < 6; i++) { await page.waitForTimeout(500); const measurement = await measureStoryCells(page); if (measurement) { sizeHistory.push({ width: measurement.width, height: measurement.height, }); console.log(`Measurement ${i}:`, measurement); } } // Verify no infinite growth if (sizeHistory.length > 0) { const initialWidth = initialMeasurements.width; const finalWidth = sizeHistory[sizeHistory.length - 1].width; const totalGrowth = finalWidth - initialWidth; console.log('Total growth:', totalGrowth, 'pixels'); // Assert growth is within acceptable limits expect(totalGrowth).toBeLessThanOrEqual(5); // 5px tolerance // Verify sizes stabilized if (sizeHistory.length >= 3) { const lastThree = sizeHistory.slice(-3); const maxDiff = Math.max(...lastThree.map((m) => m.width)) - Math.min(...lastThree.map((m) => m.width)); console.log('Max difference in last 3 measurements:', maxDiff); expect(maxDiff).toBeLessThanOrEqual(2); // Should be stable } } } }); // Take screenshot for verification await page.screenshot({ path: 'test-results/demo-round-tiles-no-titles.png', fullPage: true, }); }); test('round tiles with titles should render normally', async () => { console.log('Starting test: Round tiles with titles (control)'); // Step 1: Create a new view let viewIndex: number; await test.step('Create new view with titles', async () => { viewIndex = await createNewView(page); }); // Step 2: Configure with titles visible await test.step('Configure with visible titles', async () => { // Configure view settings and category in one operation await configureViewSettings(page, viewIndex, { mediaType: 'stories', viewType: 'row', tileType: 'round', category: TEST_CATEGORY, }); }); // Step 3: Apply theme with visible titles await test.step('Apply theme with visible titles', async () => { const themeWithVisibleTitles = { storyTiles: { title: { show: true, // Titles visible lineHeight: 13, }, circularTile: { readStrokeWidth: 2, unreadStrokeWidth: 3, }, }, }; await applyThemeToView(page, viewIndex, themeWithVisibleTitles); }); // Step 4: Verify cells render correctly await test.step('Verify cells with titles', async () => { const hasTitles = await page.evaluate(() => { const titles = document.querySelectorAll( '.storyTitle, [class*="title"]' ); return titles.length > 0; }); console.log('Has titles:', hasTitles); // Measure cells const measurements = await measureStoryCells(page); console.log('Cells with titles measurements:', measurements); if (measurements) { // Cells with titles should have reasonable dimensions expect(measurements.width).toBeGreaterThan(50); expect(measurements.width).toBeLessThan(200); } }); await page.screenshot({ path: 'test-results/demo-round-tiles-with-titles.png', fullPage: true, }); }); });