feat: add popular requests widget e2e tests (30 tests for load, display, navigation, fallback)

This commit is contained in:
2026-04-04 12:19:42 +03:00
parent 393ccfea39
commit 0ca49b9bf3
@@ -0,0 +1,245 @@
import { POPULAR_REQUESTS } from '../../support/fixtures';
describe('Popular Requests Widget', () => {
beforeEach(() => {
cy.intercept('GET', '**/api/popular-requests/**', { statusCode: 200, body: POPULAR_REQUESTS }).as('getPopularRequests');
cy.forbidGeolocation();
cy.visit('/');
});
describe('Widget Load Tests', () => {
it('Should render widget on initial page load', () => {
cy.wait('@getPopularRequests');
cy.getByTestId('popular-requests-widget').should('exist');
});
it('Should be visible in viewport', () => {
cy.wait('@getPopularRequests');
cy.getByTestId('popular-requests-widget').should('be.visible');
});
it('Should have correct styling and layout', () => {
cy.wait('@getPopularRequests');
cy.getByTestId('popular-requests-widget').should('have.css', 'display').and('not.equal', 'none');
});
it('Should have correct container dimensions', () => {
cy.wait('@getPopularRequests');
cy.getByTestId('popular-requests-widget').then(($widget) => {
expect($widget.width()).to.be.greaterThan(0);
expect($widget.height()).to.be.greaterThan(0);
});
});
it('Should display widget title/header correctly', () => {
cy.wait('@getPopularRequests');
cy.getByTestId('popular-requests-widget').within(() => {
cy.getByTestId('popular-requests-title').should('exist').and('be.visible');
});
});
});
describe('Display Tests', () => {
it('Should display all popular request items from API', () => {
cy.wait('@getPopularRequests');
cy.getByTestId('popular-request-item').should('have.length', POPULAR_REQUESTS.length);
});
it('Should display departure city in each item', () => {
cy.wait('@getPopularRequests');
cy.getByTestId('popular-request-item').each(($item, index) => {
cy.wrap($item).within(() => {
cy.getByTestId('popular-request-departure').should('contain', POPULAR_REQUESTS[index].departure);
});
});
});
it('Should display arrival city in each item', () => {
cy.wait('@getPopularRequests');
cy.getByTestId('popular-request-item').each(($item, index) => {
cy.wrap($item).within(() => {
cy.getByTestId('popular-request-arrival').should('contain', POPULAR_REQUESTS[index].arrival);
});
});
});
it('Should display flight count/frequency in each item', () => {
cy.wait('@getPopularRequests');
cy.getByTestId('popular-request-item').each(($item, index) => {
cy.wrap($item).within(() => {
cy.getByTestId('popular-request-frequency').should('exist').and('be.visible');
});
});
});
it('Should have clickable items', () => {
cy.wait('@getPopularRequests');
cy.getByTestId('popular-request-item').first().should('have.css', 'cursor').and('not.equal', 'default');
});
it('Should display items with proper styling (colors, spacing)', () => {
cy.wait('@getPopularRequests');
cy.getByTestId('popular-request-item').first().then(($item) => {
const styles = window.getComputedStyle($item[0]);
expect(styles.padding).to.not.be.empty;
expect(styles.margin).to.not.be.empty;
});
});
it('Should render all items with correct data from first request', () => {
cy.wait('@getPopularRequests');
const firstItem = POPULAR_REQUESTS[0];
cy.getByTestId('popular-request-item').first().within(() => {
cy.getByTestId('popular-request-departure').should('contain', firstItem.departure);
cy.getByTestId('popular-request-arrival').should('contain', firstItem.arrival);
cy.getByTestId('popular-request-departure-code').should('contain', firstItem.departureCode);
cy.getByTestId('popular-request-arrival-code').should('contain', firstItem.arrivalCode);
});
});
it('Should render all items with correct data from second request', () => {
cy.wait('@getPopularRequests');
const secondItem = POPULAR_REQUESTS[1];
cy.getByTestId('popular-request-item').eq(1).within(() => {
cy.getByTestId('popular-request-departure').should('contain', secondItem.departure);
cy.getByTestId('popular-request-arrival').should('contain', secondItem.arrival);
cy.getByTestId('popular-request-departure-code').should('contain', secondItem.departureCode);
cy.getByTestId('popular-request-arrival-code').should('contain', secondItem.arrivalCode);
});
});
it('Should render all items with correct data from third request', () => {
cy.wait('@getPopularRequests');
const thirdItem = POPULAR_REQUESTS[2];
cy.getByTestId('popular-request-item').eq(2).within(() => {
cy.getByTestId('popular-request-departure').should('contain', thirdItem.departure);
cy.getByTestId('popular-request-arrival').should('contain', thirdItem.arrival);
cy.getByTestId('popular-request-departure-code').should('contain', thirdItem.departureCode);
cy.getByTestId('popular-request-arrival-code').should('contain', thirdItem.arrivalCode);
});
});
it('Should display frequency/high indicator for first item', () => {
cy.wait('@getPopularRequests');
cy.getByTestId('popular-request-item').first().within(() => {
cy.getByTestId('popular-request-frequency').should('contain', POPULAR_REQUESTS[0].frequency);
});
});
});
describe('Navigation Tests', () => {
it('Should navigate to search page when clicking item', () => {
cy.wait('@getPopularRequests');
cy.getByTestId('popular-request-item').first().click();
cy.url().should('include', '/onlineboard/');
});
it('Should include departure city code in URL after click', () => {
cy.wait('@getPopularRequests');
const firstItem = POPULAR_REQUESTS[0];
cy.getByTestId('popular-request-item').first().click();
cy.url().should('include', firstItem.departureCode);
});
it('Should include arrival city code in URL after click', () => {
cy.wait('@getPopularRequests');
const firstItem = POPULAR_REQUESTS[0];
cy.getByTestId('popular-request-item').first().click();
cy.url().should('include', firstItem.arrivalCode);
});
it('Should navigate with different parameters for different items', () => {
cy.wait('@getPopularRequests');
const firstItem = POPULAR_REQUESTS[0];
const secondItem = POPULAR_REQUESTS[1];
cy.getByTestId('popular-request-item').first().click();
cy.url().then((firstUrl) => {
cy.visit('/');
cy.wait('@getPopularRequests');
cy.getByTestId('popular-request-item').eq(1).click();
cy.url().then((secondUrl) => {
expect(firstUrl).to.not.equal(secondUrl);
});
});
});
it('Should navigate to departure city page', () => {
cy.wait('@getPopularRequests');
const firstItem = POPULAR_REQUESTS[0];
cy.getByTestId('popular-request-item').first().click();
cy.url().should('include', 'departure');
});
it('Should navigate to correct date range', () => {
cy.wait('@getPopularRequests');
cy.getByTestId('popular-request-item').first().click();
cy.url().should('match', /\d{8}-\d{4}-\d{4}/);
});
it('Should preserve language on navigation', () => {
cy.visit('/en-us/');
cy.wait('@getPopularRequests');
cy.getByTestId('popular-request-item').first().click();
cy.url().should('include', '/en-us/');
});
it('Should make search page load correctly after navigation', () => {
cy.wait('@getPopularRequests');
cy.getByTestId('popular-request-item').first().click();
cy.getByTestId('board-search-result', { timeout: 10000 }).should('exist');
});
});
describe('API Fallback Tests', () => {
it('Should fall back to fixture data when API fails', () => {
// Intercept API to fail, but first reset and visit
cy.intercept('GET', '**/api/popular-requests/**', { statusCode: 500 }).as('failedRequest');
cy.visit('/');
cy.wait('@failedRequest');
// Widget should still be visible with fallback data
cy.getByTestId('popular-requests-widget').should('be.visible');
});
it('Should display fallback data correctly on API error', () => {
cy.intercept('GET', '**/api/popular-requests/**', { statusCode: 500 }).as('failedRequest');
cy.visit('/');
cy.wait('@failedRequest');
// Fallback data should still have items
cy.getByTestId('popular-request-item').should('have.length.greaterThan', 0);
});
it('Should allow navigation even with API fallback', () => {
cy.intercept('GET', '**/api/popular-requests/**', { statusCode: 500 }).as('failedRequest');
cy.visit('/');
cy.wait('@failedRequest');
cy.getByTestId('popular-request-item').first().click();
cy.url().should('include', '/onlineboard/');
});
it('Should handle network timeout gracefully', () => {
cy.intercept('GET', '**/api/popular-requests/**', (req) => {
req.destroy();
}).as('timedOutRequest');
cy.visit('/');
cy.wait('@timedOutRequest');
cy.getByTestId('popular-requests-widget').should('be.visible');
cy.getByTestId('popular-request-item').should('have.length.greaterThan', 0);
});
it('Should render widget without breaking layout on API error', () => {
cy.intercept('GET', '**/api/popular-requests/**', { statusCode: 500 }).as('failedRequest');
cy.visit('/');
cy.wait('@failedRequest');
cy.getByTestId('popular-requests-widget').then(($widget) => {
expect($widget.width()).to.be.greaterThan(0);
expect($widget.height()).to.be.greaterThan(0);
});
});
});
});