describe('testy komponentu wc-timer', () => { // Data początkowa: 1 stycznia 2025, godzina 12:00:00 const NOW_TIMESTAMP = 1735732800000; beforeEach(() => { // 1. Zamrażamy czas cy.clock(NOW_TIMESTAMP); // 2. Synchronizujemy performance.now() cy.visit('/', { onBeforeLoad(win) { cy.stub(win.performance, 'now').callsFake(() => win.Date.now()); }, }); // 3. Czekamy na definicję komponentu cy.window().then((win) => win.customElements.whenDefined('wc-timer')); }); describe('widoczność i inicjalizacja', () => { it('element jest widoczny w DOM', () => { cy.get('wc-timer').first().should('be.visible'); // SCREENSHOT 1: Stan początkowy aplikacji cy.screenshot('01-init-visible'); }); it('renderuje tekst po załadowaniu', () => { cy.get('wc-timer').first().invoke('text').should('not.be.empty'); }); }); describe('atrybuty html (declarative)', () => { it('obsługuje zmianę atrybutu target i preset', () => { const targetStr = new Date(NOW_TIMESTAMP + 2 * 3600000).toISOString(); cy.get('wc-timer').first() .invoke('attr', 'labels', 'none') .invoke('attr', 'target', targetStr) .invoke('attr', 'preset', 'hms'); cy.get('wc-timer').first().should('contain.text', '02:00:00'); // SCREENSHOT 2: Format HMS bez etykiet cy.screenshot('02-attr-preset-hms'); // Zmiana na dni-godziny-minuty cy.get('wc-timer').first() .invoke('attr', 'preset', 'dhms') .invoke('attr', 'labels', 'short'); cy.get('wc-timer').first().invoke('text').should('match', /0\s(d|dni|days)/); // SCREENSHOT 3: Format DHMS z etykietami cy.screenshot('03-attr-preset-dhms'); }); it('tryb compact ukrywa puste jednostki', () => { const targetStr = new Date(NOW_TIMESTAMP + 5 * 60000).toISOString(); cy.get('wc-timer').first() .invoke('attr', 'labels', 'none') .invoke('attr', 'compact', '') .invoke('attr', 'target', targetStr); cy.get('wc-timer').first().should('contain.text', '05:00'); // SCREENSHOT 4: Tryb compact (ukryte godziny) cy.screenshot('04-attr-compact'); }); }); describe('api javascript (imperative)', () => { it('aktualizuje widok po ustawieniu właściwości .target w JS', () => { const targetStr = new Date(NOW_TIMESTAMP + 10000).toISOString(); cy.get('wc-timer').first() .should(($el) => { expect($el[0]).to.have.property('preset'); }) .then(($el) => { const el = $el[0]; el.target = targetStr; el.preset = 'hms'; el.labels = 'none'; }); cy.get('wc-timer').first().should('contain.text', '00:00:10'); // SCREENSHOT 5: Zmiana przez JS API cy.screenshot('05-js-api-change'); }); }); describe('lokalizacja', () => { it('reaguje na zmianę atrybutu locale', () => { const targetStr = new Date(NOW_TIMESTAMP + 2 * 86400000).toISOString(); // Wersja Polska cy.get('wc-timer').first() .invoke('attr', 'target', targetStr) .invoke('attr', 'preset', 'dhms') .invoke('attr', 'labels', 'long') .invoke('attr', 'locale', 'pl'); cy.get('wc-timer').first().should('contain.text', 'dni'); // SCREENSHOT 6: Język polski cy.screenshot('06-locale-pl'); // Wersja Angielska cy.get('wc-timer').first().invoke('attr', 'locale', 'en'); cy.get('wc-timer').first().should('contain.text', 'days'); // SCREENSHOT 7: Język angielski cy.screenshot('07-locale-en'); }); }); describe('symulacja upływu czasu (ticking)', () => { it('odlicza czas w dół co sekundę', () => { const targetStr = new Date(NOW_TIMESTAMP + 10000).toISOString(); cy.get('wc-timer').first() .invoke('attr', 'preset', 'hms') .invoke('attr', 'labels', 'none') .invoke('attr', 'target', targetStr); // Start: 10 sekund cy.get('wc-timer').first().should('contain.text', '00:00:10'); // SCREENSHOT 8: Start odliczania cy.screenshot('08-tick-start'); // Przeskok o 5 sekund cy.tick(5000); cy.get('wc-timer').first().should('contain.text', '00:00:05'); // SCREENSHOT 9: Połowa czasu cy.screenshot('09-tick-middle'); // Koniec (0 sekund) cy.tick(5000); cy.get('wc-timer').first().should('contain.text', '00:00:00'); // SCREENSHOT 10: Koniec odliczania cy.screenshot('10-tick-end'); }); }); });